|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
你的留言本应该加入注册以及分页功能了,而如果你更强的话,UI(用户界面)也可以加强,完成之后,感觉是不是特有成就感?不管怎么样,咱好歹是写了一个动态网站程序了,放在自己的网站上耍耍吧。异常处置 本文面向但愿懂得PHP5异常处置机制的法式员。浏览本文你需求具有必定面向对象编程和PHP基本。
PHP5内建的异常类需求有以下成员办法:
__construct()机关函数,需求一个失足信息和一个可选的整型毛病标志作参数getMessage()获得失足信息 getCode()
失足的代码 getFile()异常产生的文件getLine()异常产生的行数 getTrace()跟踪异常每步传递的线路,存入数组,前往该数组 getTraceAsString()和getTrace()功效一样,但可以将数组中的元素转成字符串并按必定格局输入
可以看出来,Exception 类的布局和Pear_Error 很类似。当你的剧本中碰到一个毛病,你可以创立你的异常对象:
$ex = new Exception( "Could not open $this->file" );
Exception类的机关函数将承受一个失足信息和一个毛病代码。
利用 throw关头字
创立一个Exception对象后你可以将对象前往,但不该该如许利用,更好的办法是用throw关头字来取代。throw用来抛出异常:
throw new Exception( "my message", 44 );
throw 将剧本的履行中断,并使相干的Exception对象对客户代码可用。
以下是改善过的getCommandObject() 办法:
index_php5.php
<?php // PHP 5
require_once('cmd_php5/Command.php');
class CommandManager {
private $cmdDir = "cmd_php5";
function getCommandObject($cmd) {
$path = "{$this->cmdDir}/{$cmd}.php";
if (!file_exists($path)) {
throw new Exception("Cannot find $path");
}
require_once $path;
if (!class_exists($cmd)) {
throw new Exception("class $cmd does not exist");
}
$class = new ReflectionClass($cmd);
if (!$class->isSubclassOf(new ReflectionClass('Command'))) {
throw new Exception("$cmd is not a Command");
}
return new $cmd();
}
}
?>
代码中咱们利用了PHP5的反射(Reflection)API来判别所给的类是不是是属于Command 类型。在毛病的途径下履行本剧本将会报出如许的毛病:
Fatal error: Uncaught exception 'Exception' with message 'Cannot find command/xrealcommand.php' in /home/xyz/BasicException.php:10
Stack trace:
#0 /home/xyz/BasicException.php(26):
CommandManager->getCommandObject('xrealcommand')
#1 {main}
thrown in /home/xyz/BasicException.php on line 10
默许地,抛出异常招致一个fatal error。这意味着利用异常的类内建有平安机制。而仅仅利用一个毛病标志,不克不及具有如许的功效。处置毛病标志掉败只会你的剧本利用毛病的值来持续履行。
Try-catch 语句
为了进一步处置异常,咱们需求利用try-catch语句―包含Try语句和最少一个的catch语句。任何挪用 能够抛出异常的办法的代码都应当利用try语句。Catch语句用来处置能够抛出的异常。以下显示了咱们处置getCommandObject()抛出的异常的办法:
index_php5.php 后半段
<?php
// PHP 5
try {
$mgr = new CommandManager();
$cmd = $mgr->getCommandObject('realcommand');
$cmd->execute();
} catch (Exception $e) {
print $e->getMessage();
exit();
}
?>
可以看到,经由过程联合利用throw关头字和try-catch语句,咱们可以免毛病标志“净化”类办法前往的值。由于“异常”自己就是一种与其它任何对象分歧的PHP内建的类型,不会发生搅浑。
假如抛出了一个异常,try语句中的剧本将会中断履行,然后即刻转向履行catch语句中的剧本。
假如异常抛出了却没有被捕获到,就会发生一个fatal error。
处置多个毛病
在今朝为止异常处置看起来和咱们传统的作法―查验前往的毛病标识或对象的值没有甚么太大区分。让咱们将CommandManager处置地更慎重,并在机关函数中反省command目次是不是存在。
index_php5_2.php
<?php
// PHP 5
require_once('cmd_php5/Command.php');
class CommandManager {
private $cmdDir = "cmd_php5";
function __construct() {
if (!is_dir($this->cmdDir)) {
throw new Exception("directory error: $this->cmdDir");
}
}
function getCommandObject($cmd) {
$path = "{$this->cmdDir}/{$cmd}.php";
if (!file_exists($path)) {
throw new Exception("Cannot find $path");
}
require_once $path;
if (!class_exists($cmd)) {
throw new Exception("class $cmd does not exist");
}
$class = new ReflectionClass($cmd);
if (!$class->isSubclassOf(new ReflectionClass('Command'))) {
throw new Exception("$cmd is not a Command");
}
return new $cmd();
}
}
?>
这里有两个中央的挪用能够招致法式失足(__construct()和getCommandObject())。虽然如斯,咱们不需求调剂咱们的客户代码。你可以在try语句中增加浩瀚内容,然后在catch中一致处置。假如CommandManager 对象的机关函数抛出一个异常,则try语句中的履行中断,然后catch语句被挪用捕获相干的异常。一样地,getCommandObject()也是如斯。如许,咱们有同时存在两个潜伏的激发毛病的中央,和一个独一的语句来处置一切的毛病。这让咱们的代码看起来加倍整洁,又可以知足毛病处置的请求。和后面提到的PHP的传统的毛病办法比拟,明显很有优势。
index_php5_2.php 后半段
注重:虽然和index_php5.php比拟,前半段代码有两个能够失足的中央,这段代码和index_php5.php的后半段完整不异。
<?php
// PHP 5
try {
$mgr = new CommandManager(); // potential error
$cmd = $mgr->getCommandObject('realcommand');
// another potential error
$cmd->execute();
} catch (Exception $e) {
// handle either error here
print $e->getMessage();
exit();
}
?>
还有一个中央咱们没有提到。咱们如何辨别分歧类型的毛病?例如,咱们能够但愿用一种办法来处置找不到目次的毛病,而用另外一种办法来处置不法的command类。
Exception类可以承受一个可选的整型的毛病标识,这是在catch语句中辨别分歧毛病类型的一个办法。
index_php5_3.php
<?php
// PHP 5
require_once('cmd_php5/Command.php');
class CommandManager {
private $cmdDir = "cmd_php5";
const CMDMAN_GENERAL_ERROR = 1;
const CMDMAN_ILLEGALCLASS_ERROR = 2;
function __construct() {
if (!is_dir($this->cmdDir)) {
throw new Exception("directory error: $this->cmdDir", self::CMDMAN_GENERAL_ERROR);
}
}
function getCommandObject($cmd) {
$path = "{$this->cmdDir}/{$cmd}.php";
if (!file_exists($path)) {
throw new Exception("Cannot find $path", self::CMDMAN_ILLEGALCLASS_ERROR);
}
require_once $path;
if (!class_exists($cmd)) {
throw new Exception("class $cmd does not exist", self::CMDMAN_ILLEGALCLASS_ERROR);
}
$class = new ReflectionClass($cmd);
if (!$class->isSubclassOf(new ReflectionClass('Command'))) {
throw new Exception("$cmd is not a Command", self::CMDMAN_ILLEGALCLASS_ERROR);
}
return $class->newInstance();
}
}
?>
经由过程传递 CMDMAN_ILLEGALCLASS_ERROR和 CMDMAN_GENERAL_ERROR个中之一的参数给咱们抛出的异常对象,咱们就能够让客户代码辨别分歧类型的毛病,并界说分歧的处置战略。
index_php5_3.php
<?php // PHP 5
try {
$mgr = new CommandManager();
$cmd = $mgr->getCommandObject('realcommand');
$cmd->execute();
} catch (Exception $e) {
if ($e->getCode() == CommandManager::CMDMAN_GENERAL_ERROR) {
// no way of recovering
die($e->getMessage());
} else if ($e->getCode() == CommandManager::CMDMAN_ILLEGALCLASS_ERROR) {
error_log($e->getMessage());
print "attempting recovery\n";
// perhaps attempt to invoke a default command?
}
}
?>
咱们也能够用另外一种办法来完成如许的后果―从最基本的Exception类中派生出代表分歧类型异常的子类,再抛出和捕获。
[1] [2] 下一页
只要实现最基本的功能就可以了 就是可以添加留言 然后可以显示留言,然后加入管理功能 |
|