PHP错误与异常处理(二)

自定义错误处理器

   我们写程序,难免会有问题(是经常会遇到问题),而PHP遇到错误时,就会给出出错脚本的位置、行数和原因。有很多人说,这并没有什么大不了。确实,在调试程序阶段,这确实是没啥的,而且我认为给出错误路径是必要的。但泄露了实际路径的后果是不堪设想的,对于某些入侵者,这个信息可是非常重要,而事实上现在有很多的服务器都存在这个问题。

   有些人干脆把PHP配置文件中的display_errors设置为Off来解决(貌似我们就是这样做的),但本人认为这个方法过于消极。有些时候,我们的确需要PHP返回错误的信息以便调试。而且在出错时也可能需要给用户一个交待,甚至导航到另一页面。

   而set_error_handle函数就可以帮助我们放置错误信息泄露。

set_error_handler
set_error_handler ( callable $error_handler [, int $error_types = E_ALL | E_STRICT ] )

第一个参数是放置一个回调函数。第二个参数是设置哪些错误级别出现时触发这个自定义的错误处理函数。

注:PHP中每一个错误的触发几乎都会产生四个元素:错误代号(error)、错误信息(message)、错误的文件名(file)和错误的行号(line)。

   本函数可以用你自己定义的方式来处理运行中的错误, 例如,在应用程序中严重错误发生时,或者在特定条件下触发了一个错误(使用 trigger_error()),你需要对数据/文件做清理回收。

   重要的是要记住 error_types 里指定的错误类型都会绕过 PHP 标准错误处理程序, 除非回调函数返回了 FALSE。error_reporting()设置将不会起到作用而你的错误处理函数继续会被调用 —— 不过你仍然可以获取 error_reporting的当前值,并做适当处理。 需要特别注意的是带 @ error-control operator前缀的语句发生错误时,这个值会是 0。同时注意,在需要时你有责任使用 die()。 如果错误处理程序返回了,脚本将会继续执行发生错误的后一行。

   以下级别的错误不能由用户定义的函数来处理: E_ERROR、 E_PARSE、 E_CORE_ERROR、 E_CORE_WARNING、E_COMPILE_ERROR、 E_COMPILE_WARNING,和在调用 set_error_handler() 函数所在文件中产生的大多数 E_STRICT。

   如果错误发生在脚本执行之前(比如文件上传时),将不会调用自定义的错误处理程序因为它尚未在那时注册。下面简单的看一下这个函数的用法:

<?php
/**
 
* 自定义错误处理
*
//set_error_handler(callable $error_handler [, int $error_types=E_ALL | E_STRICT ])
header('Content-type:text/html;charset=utf-8');
function my_error_id($error,$errmsg,$file,$line){
    echo "<b>错误代码:</b>[{$error}]{$errmsg}<br />" . PHP_EOL;
    echo "<b>错误行号:</b>{$file}文件下的{$line}行<br />" . PHP_EOL; 
    echo "<b>PHP版本:</b>" . PHP_VERSION . "(" .PHP_OS . ")"; 
  }
set_error_handler('my_error_id',E_ALL&~E_NOTICE); 
//设置出现除了NOTICE以外的错误级别时触发my_error_id函数 
echo $error;echo '<hr />';//提醒级别的错误
settype($var,'a');//警告级别的错误
?>

运行的结果为:

图片.png

  当然,php还给我们提供了一个取消自定义错误处理的回收机制,也就是函数restore_error_handler(),只有在这个函数之后的错误,都会采用系统内置的报错方法。

注:这里这是大致的演示,具体的想要怎样的错误处理机制,自行封装。如果想要捕捉E_ERROR的致命错误,单单这个函数无法做到,因为致命错误一发生时,会中止脚本的进行,所有,如果想要捕捉,就要用register_shutdown_function函数来配合使用。然而,在PHP7以上,E_ERROR的错误可以交由set_exception_handler,即自定义异常来捕获。


2 Comments

  1. 头像
    琴音 回复
    2017-06-26 13:35:50

    肇大神好厉害

头像
QQ登录: