26.6 巧妙地处理错误

对于有C++或Java编程经历的人来说,可能会很习惯使用异常处理。异常处理允许函数发出信号通知错误出现,并将错误处理交给一个专门的异常处理程序。异常机制是在大型项目中处理错误的好方法。关于异常处理,我们已经在第7章“错误和异常处理”中详细介绍,这里就不再重复。

你已经了解如何触发自己的错误。你也可以提供错误处理程序来捕获错误。

当用户级别的错误、警告和通知发生时,set_error_handler()函数可以提供一个可供调用的函数,可以将用作错误处理程序的函数名称作为set_error_handler()的参数。

错误处理函数必须带有两个参数:错误类型和错误信息。基于这两个参数变量,函数可以决定如何解决这个错误。其中,错误类型应该是已经定义好的错误类型常量。错误信息则是一个描述性字符串。

如下所示的是set_error_handler()函数的调用:


set_error_handler('my_error_handler');


以上调用将告诉PHP调用一个名为my_error_handler()的函数来进行错误处理操作,此外,还要提供该函数的具体实现方法。该函数原型如下所示:


My_error_handler(int error_type,string error_msg

[,string errfile[,int errline[,array errcontext]]]))


但是,该函数的具体实现可以由自己来设定。

传递给处理程序函数的参数如下:

■错误类型

■错误消息

■发生错误的文件

■发生错误的行号

■符号表——也就是,发生错误时所有变量及其值的集合

该函数的逻辑行为可能包括:

■显示系统提供的错误信息

■将信息存储到日志文件

■将错误以电子邮件形式发送到一个邮箱

■调用一个exit,中断脚本执行

程序清单26-2所示的脚本声明了一个错误处理程序,并调用函数set_error_handler()设置它,然后生成了一些错误。

程序清单26-2 handle.php——该脚本声明和定制了一个错误处理程序并生成不同的错误


<?php

//The error handler function

function myErrorHandler($errno,$errstr,$errfile,$errline){

echo"<br/><table bgcolor=\"#cccccc\"><tr><td>

<p><strong>ERROR:</strong>".$errstr."</p>

<p>Please try again,or contact us and tell us

that the error occurred in line".$errline."of

file".$errfile."</p>";

if(($errno==E_USER_ERROR)||($errno==E_ERROR)){

echo"<p>This error was fatal,program ending</p>

</td></tr></table>";

//close open resources,include page footer,etc

exit;

}

echo"</td></tr></table>";

}

//Set the error handler

set_error_handler('myErrorHandler');

//trigger different levels of error

trigger_error('Trigger function called',E_USER_NOTICE);

fopen('nofile','r');

trigger_error('This computer is beige',E_USER_WARNING);

include('nofile');

trigger_error('This computer will self destruct in 15 seconds',E_USER_ERROR);

?>


以上脚本的输出结果如图26-1所示。

26.6 巧妙地处理错误 - 图1

图 26-1 如果使用自己的错误处理程序,可以设置比PHP更友好的错误信息

以上自定义的错误处理程序的功能并不比默认的错误处理程序强很多。因为这段代码是由我们自己实现的,所以可以让它做任何事情。通过它可以在出错的时候选择性地告诉访问者一些有用的信息,以及如何显示该信息,这样就可以与网站其他部分的内容相协调。更重要的是,我们可以灵活地决定发生什么事情:脚本是否应该继续执行?信息是否应该记录到日志或将它显示出来吗?要对技术支持发出警告吗?

需要注意的一点是,自定义错误处理函数将无法处理所有的错误类型。有些错误,例如,解析错误和致命的运行时错误,还是会触发默认的错误处理函数。如果需要考虑到这种情况,需确认在将参数传递给能够产生致命错误,或触发自定义的E_USER_ERROR级别错误之前,仔细检查这些参数。

这里再介绍一个有用的新特征:如果错误处理程序返回了false值,PHP的内置错误处理程序将被调用。这样,可以处理EUSER*错误,并由内置处理程序处理常见错误。