1. 什么是异常?
异常是程序运行中由外部环境引起的意外情况,使程序无法按照正常流程执行下去。
2. PHP异常处理机制
在 PHP 代码中所产生的异常可被 throw 语句抛出并被 catch 语句捕获。需要进行异常处理的代码都必须放入 try 代码块内,以便捕获可能存在的异常。每一个 try 至少要有一个与之对应的 catch。
try{ //可能出现错误或异常的代码 } catch(Exception $e){
//对异常处理,方法: //1、自己处理 //2、不处理,将其再次抛出 } |
捕获后对异常的处理:1对于定时多次执行的程序可将异常信息保存到数据库里。
2调试阶段可以输出堆栈信息以便快速发现问题,
try { throw new Exception('a Exception'); } catch (Exception $e) { echo "MESSAGE = " . $e->getMessage() . "\n" . "STACK TRACE = \n" . $e->getTraceAsString() ;
} |
3发布后输出异常信息即可。
try { throw new Exception('a Exception'); } catch (Exception $e) { echo "MESSAGE = " . $e->getMessage() ; } |
使用多个 catch 可以捕获不同的类所产生的异常。
<?php class customException extends Exception { public function errorMessage() { $errorMsg = 'Error on line ' . $this->getLine () . ' in ' . $this->getFile () . ': <b>' . $this->getMessage () . '</b> is not a valid E-Mail address'; return $errorMsg; } } $email = "someone@example.com"; try { if (filter_var ( $email, FILTER_VALIDATE_EMAIL ) === FALSE) { throw new customException ( $email ); } if (strpos ( $email, "example" ) !== FALSE) { throw new Exception ( "$email is an example e-mail" ); } } catch ( customException $e ) { echo $e->errorMessage (); } catch ( Exception $e ) { echo $e->getMessage (); } ?> |
当 try 代码块不再抛出异常或者找不到 catch 能匹配所抛出的异常时,PHP 代码就会在跳转到最后一个 catch 的后面继续执行。当然,PHP 允许在 catch 代码块内再次抛出(throw)异常。当一个异常被抛出时,抛出异常时所在的代码块后边的代码将不会继续执行,而 PHP 就会尝试查找第一个能与之匹配的 catch。
如果一个异常没有被捕获,可以使用 set_exception_handler() 作相应的处理,必须在异常抛出前定义一个异常处理函数$exception_handler,并用
set_exception_handler($exception_handler) 设置为默认异常处理器,用于没有用 try/catch 块来捕获的异常。例子:
<?php function exception_handler($exception) { echo "Uncaught exception: " , $exception->getMessage(), "\n"; }
set_exception_handler('exception_handler');
throw new Exception('An Exception');
?> |
以上程序输出为:Uncaught exception: An Exception
如果异常没有被捕获并且没有使用set_exception_handler()作相应的处理
那么 PHP 将会产生一个严重的错误,并且输出 Uncaught Exception ... (未捕获异常)的提示信息。
如下:
<?php throw new Exception('An Exception'); ?> |
以上程序输出:Fatal error: Uncaught exception 'Exception' with message 'An Exception' in D:\xampp\htdocs\woo\exception\1.php:2 Stack trace: #0 {main} thrown in D:\xampp\htdocs\woo\exception\1.php on line 2
3.Zendframework如何处理异常
Zend_Controller_Front 默认将捕捉所有异常并注册到响应对象,响应对象默认不会显示异常消息。
默认地,错误处理器插件(error handler plugin) 将会被注册并激活。它作为一个postDispatch()插件,检查分发器、动作控制器或者其他的异常是否发生。异常的抓取被记录在一个对象里,这个对象注册在请求里。使用Zend_Controller_Action::_getParam('error_handler')来读取它.如果发生异常,它将转向一个错误处理控制器ErrorController::errorAction()。异常由错误管理器通过抓取error_handler对象的exception属性来触发的。
public function errorAction() { //获取error_handler对象 $errors = $this->_getParam('error_handler'); switch ($errors->type) { case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER: case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION: $this->getResponse()->setHttpResponseCode(404); break; default: // application error $this->getResponse()->setHttpResponseCode(500); break; } //获取异常 $exception = $errors->exception; 对异常处理根据不同情况传给view输出或者保存到数据库里。 } |
4.PHP错误处理机制
在 PHP 中,默认的错误处理很简单。一条消息会被发送到浏览器,这条消息带有文件名、行号以及一条描述错误的消息。
例如
<?php $file=fopen("welcome.txt","r"); ?> |
结果是:Warning: fopen(welcome.txt): failed to open stream: No such file or directory in D:\xampp\htdocs\woo\error\2.php on line 2
基本的错误处理:使用 die() 函数
<?php if(!file_exists("welcome.txt")) { die("File not found"); } else { $file=fopen("welcome.txt","r"); } ?> |
在错误之后终止了脚本并输出自定义信息。
创建自定义错误处理器
先创建一个处理错误的函数,该函数必须有能力处理至少两个参数 (error level 和 error message),但是可以接受最多五个参数(可选的:file, line-number 以及 error context)
function errorHandler($errNo,$errMsg){ echo "<b>Error:</b> [$errNo] $errMsg<br />"; echo "Ending Script"; die(); } |
用set_error_handler设置errorHandler为错误处理函数。
<?php function errorHandler($errNo,$errMsg){ echo "<b>Error:</b> [$errNo] $errMsg<br />"; echo "Ending Script"; die(); } set_error_handler("errorHandler");
$test=2; if ($test>1) { //触发错误 trigger_error("Value must be 1 or below",E_USER_WARNING); } ?> |
输出:Error: [512] Value must be 1 or below
Ending Script
也可以在错误处理函数中将错误信息托管至ErrorException,再处理。
function errorExceptionHandler($errNo, $errMsg, $errFile, $errLine) { if (in_array($errNo, array(E_USER_ERROR, E_ERROR))) { throw new ErrorException($errMsg, 0, $errNo, $errFile, $errLine); } return false; } |