1.Exception类
这个类是PHP为异常处理提供的内置类。html' target='_blank'>构造函数的两个参数分别是错误消息和错误代码。
除了构造函数之外,该类还提供了如下的内置方法:
· getCode() 返回传递给构造函数的代码
· getMessage() 返回传递给构造函数的消息
· getFile() 返回产生异常的代码文件的完整路径
· getLine() 返回代码文件中产生异常的代码行号
· getTrace() 返回一个包含了产生异常的代码回退路径的数组
· getTraceAsString() 返回与getTrace()方向相同的信息,该信息将被格式化成一个字符串。
· _toString() 允许简单地显示一个Exception对象,并且给出以上所有方法可以提供的信息。
通过执行以下命令,可以获得相同的异常信息(以及代码回退路径):
echo $e;
回退路径显示了在发生异常时所执行的函数。
2.异常控制结构
异常处理的基本思想是代码在try代码块被调用执行。在PHP中,异常必须手动抛出。
异常控制结构:try...throw...catch
可以将多个catch代码块与一个try代码块进行关联。还可以在一个catch代码块产生新的异常。
如下代码抛出并捕获一个异常:
<?phptry { throw new Exception('A terrible error has occurred', 42);}catch (Exception $e) { echo 'Exception '. $e->getCode(). ': '. $e->getMessage().'<br />'. ' in '. $e->getFile(). ' on line '. $e->getLine(). '<br />';}?>
这里我们使用了exception类的前四个方法,catch代码块报告了异常错误信息以及发生错误位置的说明。
3.用户自定义异常
可以扩展Exception类来创建自己的异常类。
可能需要继承的代码:
<?php class Exception{ function __construct(string $message=NULL,int $code=0){ if(func_num_args()){ $this->message = $message; } $this->code = $code; $this->file = __FILE__; // of throw clause $this->line = __LINE__; // of throw clause $this->trace = debug_backtrace(); $this->string = StringFormat($this); } protected $message = 'Unknown exception '; // exception message protected $code = 0; // user defined exception code protected $file; // source filename of exception protected $line; // source line of exception private $trace; // backtrace of exception private $string; // internal only!! final function getMessage(){ return $this->message; } final function getCode(){ return $this->code; } final function getFile(){ return $this->file; } final function getTrace(){ return $this->trace; } final function getTraceAsString(){ return self::TraceFormat($this); } function _toString(){ return $this->string; } static private function StringFormat(Exception $exception){ // ... a function not available in PHP scripts // that returns all relevant information as a string } static private function TraceFormat(Exception $exception){ // ... a function not available in PHP scripts // that returns the backtrace as a string }}?>
该类的大多数公有方法都是final的:这就意味着不能重载这些方法。我们可以创建自己的Exception子类,但是不能改变这些基本方法的行为。请注意,_toString()函数可以重载,因此我们可以改变异常的显示方式。也可以添加自己的方法。
用户自定义的Exception类示例:
<?phpclass myException extends Exception{ function __toString() { return '<table border='1'> <tr> <td><strong>Exception '.$this->getCode().' </strong>: '.$this->getMessage().'<br />'.' in '.$this->getFile().' on line '.$this->getLine().' </td> </tr> </table><br />'; }}try{ throw new myException('A terrible error has occurred', 42);}catch (myException $m){ echo $m;}?>
在以上代码中,我们声明了一个新的异常类myException,该类扩展了Exception基类。该类与Exception类之间的差异在于重载了_toString()方法,从而为打印异常提供了一个更好的方法。
4.文件I/O相关的异常
写文件时可能会出现三种情况的错误:文件无法打开、无法获得写锁或者文件无法写入。我们为每一种可能性都创建了一个异常类:
<?phpclass fileOpenException extends Exception{ function __toString() { return 'fileOpenException '. $this->getCode() . ': '. $this->getMessage().'<br />'.' in ' . $this->getFile(). ' on line '. $this->getLine() . '<br />'; }}class fileWriteException extends Exception{ function __toString() { return 'fileWriteException '. $this->getCode() . ': '. $this->getMessage().'<br />'.' in ' . $this->getFile(). ' on line '. $this->getLine() . '<br />'; }}class fileLockException extends Exception{ function __toString() { return 'fileLockException '. $this->getCode() . ': '. $this->getMessage().'<br />'.' in ' . $this->getFile(). ' on line '. $this->getLine() . '<br />'; }}?>
Exception类的这些子类并没有执行任何特别的操作。事实上,对于这个应用程序的作用来说,可以让它们成为空的子类或者使用PHP所提供的Exception类。然而,我们为每个子类提供了_toString()方法,从而可以解释所发生的异常类型:
<?php require_once('file_exceptions.php'); // create short variable names $tireqty = $_POST['tireqty']; $oilqty = $_POST['oilqty']; $sparkqty = $_POST['sparkqty']; $address = $_POST['address']; $DOCUMENT_ROOT = $_SERVER['DOCUMENT_ROOT'];?><html><head> <title>Bob's Auto Parts - Order Results</title></head><body><h3>Bob's Auto Parts</h3><h4>Order Results</h4><?php$date = date('H:i, jS F');echo '<p>Order processed at '.$date.'</p>';echo '<p>Your order is as follows: </p>';$totalqty = 0;$totalqty = $tireqty + $oilqty + $sparkqty;echo 'Items ordered: '.$totalqty.'<br />';if( $totalqty == 0) { echo 'You did not order anything on the previous page!<br />';} else { if ( $tireqty > 0 ) { echo $tireqty.' tires<br />'; } if ( $oilqty > 0 ) { echo $oilqty.' bottles of oil<br />'; } if ( $sparkqty > 0 ) { echo $sparkqty.' spark plugs<br />'; }}$totalamount = 0.00;define('TIREPRICE', 100);define('OILPRICE', 10);define('SPARKPRICE', 4);$totalamount = $tireqty * TIREPRICE + $oilqty * OILPRICE + $sparkqty * SPARKPRICE;$totalamount=number_format($totalamount, 2, '.', ' ');echo '<p>Total of order is '.$totalamount.'</p>';echo '<p>Address to ship to is '.$address.'</p>';$outputstring = $date.' '.$tireqty.' tires '.$oilqty.' oil ' .$sparkqty.' spark plugs $'.$totalamount .' '. $address.'';// open file for appendingtry{ if (!($fp = @fopen('$DOCUMENT_ROOT/../orders/orders.txt', 'ab'))) throw new fileOpenException(); if (!flock($fp, LOCK_EX)) throw new fileLockException(); if (!fwrite($fp, $outputstring, strlen($outputstring))) throw new fileWriteException(); flock($fp, LOCK_UN); fclose($fp); echo '<p>Order written.</p>';}catch (fileOpenException $foe){ echo '<p><strong>Orders file could not be opened. Please contact our webmaster for help.</strong></p>';}catch (Exception $e){ echo '<p><strong>Your order could not be processed at this time. Please try again later.</strong></p>';}?></body></html>
可以看到,以上脚本的文件I/O部分被封装在一个try代码块中。通常,良好的编码习惯要求try代码块的代码量较少,并且在代码块的结束处捕获相关异常。这使得异常处理代码更容易编写和维护,因为可以看到所处理的内容。
如果无法打开文件,将抛出一个fileOpenException异常;如果无法锁定该文件,将抛出一个fileLockException异常;而如果无法写这个文件,将抛出一个fileWriteException异常。
我们给出了两个catch代码块:一个用来处理fileOpen-Exception异常,而另一个用来处理Exception。由于其他异常都是从Exception继承过来的,它们将被第二个catch代码块捕获。catch代码块与每一个instanceof操作符相匹配。这就是为每一个类扩展自己异常类的理由。
如果异常没有匹配的catch语句块,PHP将报告一个致命错误。
请注意fopen()函数的调用仍然使用了@错误抑制操作符前缀。如果该函数调用失败,PHP将发出一个警告,根据php.ini中的错误报告设置不同,该警告可能会被报告或者记录。无论是否产生一个异常,这个警告仍然会发出。
好了,从零开始攻略PHP系列到这里就水完了,仅供参考,好多我也是一知半解,只是整理出来方便查阅。下个月会陆续发一些数据库的,也就是该书整理的第二篇。
PHP编程郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。
新闻热点
疑难解答