10.5PHP错误和异常处理
10.5 PHP错误和异常处理
无论是初学者还是经验丰富的程序员,编写的程序都可能存在各种各样的错误,这些错误会降低软件的稳定性,PHP中提供了完善的错误和异常处理机制。
10.5.1 PHP的错误处理机制
在PHP 4中,没有异常Exception这个概念,只有错误Error。可以通过修改php.ini文件来配置用户端输出的错误信息。
在php.ini中,一个分号“;”表示注释。下面列出几种常用的类型。
(1);E_ALL:所有的错误和警告。
(2);E_ERROR:致命的运行时错误。
(3);E_RECOVERABLE_ERROR:几乎致命的运行时错误。
(4);E_WARNING :运行时的警告(非致命错误)。
(5);E_PARSE:编译时解析错误。
(6);E_NOTICE:运行时的提示,这些提示常常是由代码中的bug引起的。
在php.ini中,error_reporting控制输出到用户端的消息种类。可以把上面的类型自由组合然后斌值给error_reporting。例如:
error_reporting = E_ALL表示输出所有的信息。
error_reporting = E_ALL & ~E_NOTICE表示输出所有的错误,除了提示。
在php.ini中,display_errors可以设置是否将以上设置的错误信息输出到用户端。
display_errors = On输出到用户端(调试代码时候,打开这项更方便)。
display_errors = Off消息将不会输出到用户端(最终发布时应改成Off)。
除了在php.ini文件中可以调整错误消息的显示级别外,在PHP代码中也可以自定义消息显示的级别。PHP提供了一个方便的调整函数:
int error_reporting ( [int level] )
使用这个函数可以定义当前PHP页面中错误消息的显示级别。参数level使用了二进制掩码组合的方式。
错误类型见表10-5。
表10-5 错误类型列表
| 错误类型 | 对应值 |
| E_ERROR | 1 |
| E_WARNING | 2 |
| E_PARSE | 4 |
| E_NOTICE | 8 |
| E_CORE_ERROR | 16 |
| E_CORE_WARNING | 32 |
| E_COMPILE_ERROR | 64 |
| E_COMPILE_WARNING | 128 |
| E_USER_ERROR | 256 |
| E_USER_WARNING | 512 |
| E_USER_NOTICE | 1024 |
| E_ALL | 2047 |
| E_STRICT | 2048 |
| E_RECOVERABLE_ERROR | 4096 |
例10-8 显示所有错误,代码如下。
<?php //显示所有错误 error_reporting(E_ALL); echo $a; echo "<br>"; echo "ok"; ?>
结果提示$a变量未定义,输出如图10-7所示。

图10-7 错误显示结果
例10-9 显示所有错误,除了提示,代码如下。
<?php //显示所有错误,除了提示 error_reporting(E_ALL^E_NOTICE); echo $a; echo "<br>"; echo "ok"; ?>
结果会顺利通过编译,最后输出如图10-8所示。

图10-8 忽略错误
例10-10 出现警告,代码如下。
<?php //出现警告 error_reporting(E_ALL); echo 2/0; ?>
最后会出现警告,如图10-9所示。

图10-9 显示警告错误
例10-11 显示所有错误,除了警告,代码如下。
<?php //显示所有错误,除了警告 error_reporting(E_ALL^E_WARNING); echo 2/0; echo "<br>"; echo "ok"; ?>
结果会顺利通过编译输出,结果如图10-10所示。

图10-10 忽略警告信息
10.5.2 自定义错误处理
可以使用set_error_handler函数自定义错误处理函数,然后使用trigger_error函数来触发自定义函数。
例10-12 自定义错误处理。
<?php
//自定义错误处理函数
function customError($errno, $errstr, $errfile, $errline) {
echo "<b>Custom error:</b> [$errno] $errstr<br />";
echo " Error on line $errline in $errfile<br />";
echo "Ending Script"; die();
}
//set error handler
set_error_handler("customError");
$test=0; //trigger error
if ($test==0) {
trigger_error("A custom error has been triggered");
}else{
echo intval(100/$test);
}
?>
结果输出如图10-11所示。

图10-11 自定义错误提示
10.5.3 PHP异常处理
异常处理是PHP 5中新增的更高的错误处理机制,它会在指定的错误发生时改变脚本的正常流程,是PHP 5提供的一种新的面向对象的错误处理方法。
1.异常的抛出与捕获
PHP 5中使用try…catch语句捕获并处理异常。使用异常的函数应该位于try代码块内。如果没有触发异常,则代码将照常继续执行。但是如果异常被触发,会抛出一个异常。throw语句规定如何触发异常。每一个throw必须对应至少一个catch,catch代码块会捕获异常,并创建一个包含异常信息的对象。语法如下。
try{
//可能引发异常的语句
}catch(异常类型 异常实例){
//异常处理语句
}
当异常被抛出时,其后的代码不会继续执行,PHP会尝试查找匹配的catch代码块。如果异常没有被捕获,而且又没用使用set_exception_handler()做相应的处理的话,那么将发生一个严重的错误(致命错误),并且输出“Uncaught Exception”(未捕获异常)的错误消息。
例10-13 异常的使用,代码如下。
<?php
//创建可抛出一个异常的函数
function checkNum($number)
{
if($number>1)
{
throw new Exception("参数必须<=1");
}
return true;
}
//在try代码块中触发异常
try
{
checkNum(2);
}
//捕获异常
catch(Exception $e)
{
echo "Message: " .$e->getMessage();
}
?>
结果输出如图10-12所示。

图10-12 异常抛出与捕获
2.基本异常类介绍
PHP的基本异常(Exception)类是PHP 5的一个基本内置类,该类用于脚本发生异常时,创建异常对象,该对象用于存储异常信息及抛出和捕获。Exception类的构造方法需要接收两个参数:错误信息与错误代码,如下。
class Exception
{
protected $message = "Unknown exception"; //异常信息
protected $code = 0; //用户自定义异常代码
protected $file; //发生异常的文件名
protected $line; //发生异常的代码行号
function __construct($message = null, $code = 0);
final function getMessage(); //返回异常信息
final function getCode(); //返回异常代码
final function getFile(); //返回发生异常的文件名
final function getLine(); //返回发生异常的代码行号
final function getTrace(); //backtrace() 数组
final function getTraceAsString(); //已格成化成字符串的 getTrace() 信息
/* 可重载的方法 */
function __toString(); //可输出的字符串
}
3.自定义异常
PHP 5中可以自定义异常,自定义的异常必须继承自Exception类或者它的子类。
例10-14 自定义异常,代码如下。
<?php
class emailException extends Exception{
public function errorMessage()
{
//异常信息
$errorMsg = "Error on line ".$this->getLine()." in ".$this->getFile()
.": <br>".$this->getMessage()."不是合法的Email";
return $errorMsg;
}
}
$email = "usrname@HBSI...com";
try
{
if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE)
{
//邮件不合法,抛出异常
throw new emailException($email);
}
}catch (emailException $e){
//显示自定义的错误信息
echo $e->errorMessage();
}
?>
最后输出如图10-13所示。

图10-13 自定义异常抛出与捕获
4.捕获多个异常
PHP 5中可以使用多个来catch接收多个异常。
例10-15 接收多个异常,代码如下。
<?php
class emailException extends Exception{
public function errorMessage()
{
//异常信息
$errorMsg = "Error on line ".$this->getLine()." in ".$this->getFile()
.": <br>".$this->getMessage()."不是合法的Email";
return $errorMsg;
}
}
$email = "HBSI@example..com";
try
{
if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE)
{
//抛出异常
throw new emailException($email);
}
//检测是否是示例邮件
if(strpos($email, "example") !== FALSE)
{
throw new Exception("邮件是一个示例邮件");
}
}
catch (emailException $e)
{
echo $e->errorMessage();
}
catch(Exception $e)
{
echo $e->getMessage();
}
?>
最后输出如图10-14所示。

图10-14 捕获多异常
如果将邮件换成$email = "HBSI@example..com",结果输出如图10-15所示。

图10-15 多异常捕获示例
下一篇:小结
