php的错误注册处理函数
背景:
以前看tp的相关源码,有一段错误处理函数逻辑,看了下里面的源码,针对错误处理,大概有以下几个函数。
- set_error_handler — 设置用户自定义的错误处理函数
本函数可以用你自己定义的方式来处理运行中的错误, 例如,在应用程序中严重错误发生时,或者在特定条件下触发了一个错误(使用 trigger_error()),你可以在处理函数做一些日志记录功能,这个处理函数能处理一些像notic,waring,人为触发错误等,像falter error,parse error是没有效果的。
注意:如果错误发生在脚本执行之前,将不会调用自定义的错误处理程序因为它尚未在那时注册
- set_exception_handler — 设置用户自定义的异常处理函数
当一个未捕获的异常发生时所调用函数的名称,用于没有用 try/catch 块来捕获的异常。 在 exception_handler 调用后异常会中止
- register_shutdown_function — 注册一个会在php中止时执行的函数
常用于在注册一个导致php中止的致命错误的处理函数,像falter error,parse error等。
通过自己做的一些尝试,发现了一些在错误处理函数上需要注意的地方,上代码。
文件一 app.php
<?php class App{ public function __construct() { $this->error(); } public function error() { set_error_handler([$this,'_error_handler']); set_exception_handler([$this,'_exception_handler']); register_shutdown_function([$this,'_error_register']); } //记录日志 public function errlog($type,$msg,$file,$line) { $time = date('Y-m-d H:i:s')."\r\n"; $type = '错误代码:'.$type."\r\n"; $msg = '错误信息:'.$msg."\r\n"; $file = '错误文件:'.$file."\r\n"; $line = '错误行数:'.$line."\r\n\r\n"; error_log($time.$type.$msg.$file.$line,3,str_replace('\\', '/', __dir__).'/error.log'); } //异常处理函数 public function _exception_handler(Throwable $exception) { if($exception instanceof Exception){ }elseif ($exception instanceof Error) { } $this->errlog($exception->getCode(),$exception->getMessage(),$exception->getFile(),$exception->getLine()); } //错误处理函数 public function _error_handler($errno, $errstr, $errfile, $errline) { $this->errlog($errno,$errstr,$errfile,$errline); } //在php中止时执行的函数 public function _error_register() { if($err = error_get_last()){ $this->errlog($err['type'],$err['message'],$err['file'],$err['line']); } } } if(defined('DEBUG')){//开发模式 error_reporting(E_ALL); }else{ error_reporting(0); } $app = new App(); //模拟各种错误的文件 require 'err_include.php';
文件二 err_include.php
<?php //error_reporting(0); foobar(3, 5);//Fatal error级别的错误,在当前页面关闭错误报告并且注册了php中止时执行的函数(register_shutdown_function)的情况下,仍然会爆出错误并且不会运行中止注册函数 /* Parse error级别的错误,在当前页面关闭错误报告并且注册了php中止时执行的函数(register_shutdown_function)的情况下, 仍然会爆出错误并且不会运行中止注册函数 可以在另一个页面引入出现致命错误的页面,然后 */ var_dump(23+-+); // notice级别的错误,在当前页面关闭错误报告并且了注册错误处理函数(set_error_handler)的情况下,不会爆出错误,与falter error,parse error不同 echo $foo['bar']; //人为触发错误,在当前页面关闭错误报告并且注册了错误处理函数(set_error_handler)的情况下,不会爆出错误,并且会运行注册的处理函数,与falter error,parse error不同
trigger_error('人为触发一个错误', E_USER_ERROR);
//模拟产生Warning 错误,与上面类似
include 'xyz.php';
//抛出异常,在当前页面关闭错误报告并且注册了异常处理函数(_exception_handler)的情况下,不会爆出错误,并且会运行注册的处理函数
throw new Exception('This is a exception', 400);
总结:
- 当捕获处理致命错误、编译错误时,会发现在致命错误、编译错误当前的页面是无法捕获的,并且无法关闭错误报告,需要到另一个没有致命错误的页面通过包含错误页面然后捕获
- err_log()这个函数,必须写绝对文件路径,不然会写不进文件

浙公网安备 33010602011771号