set_error_handler()
register_shutdown_function()
set_exception_handler()
原文: https://blog.csdn.net/wenzhibincom/article/details/84555822
-----------------------------------------------------------
前面提到框架中是可以捕获所有的错误和异常的,之所以能实现应该是使用了黑科技,哈哈!其实也不是什么黑科技,主要是三个重要的函数:
1:set_error_handler()
看到这个名字估计就知道什么意思了,这个函数用于捕获错误,设置一个用户自定义的错误处理函数。
-
1
-
2 set_error_handler('zyferror');
-
3 function zyferror($type, $message, $file, $line)
-
4 {
-
5 var_dump('<b>set_error_handler: ' . $type . ':' . $message . ' in ' . $file . ' on ' . $line . ' line .</b><br />');
-
6 }
-
7
当程序出现错误的时候自动调用此方法,不过需要注意一下两点:第一,如果存在该方法,相应的error_reporting()就不能在使用了。所有的错误都会交给自定义的函数处理。第二,此方法不能处理以下级别的错误:E_ERROR、 E_PARSE、 E_CORE_ERROR、 E_CORE_WARNING、 E_COMPILE_ERROR、 E_COMPILE_WARNING,set_error_handler() 函数所在文件中产生的E_STRICT,该函数只能捕获系统产生的一些Warning、Notice级别的错误。
并且他有多种调用的方法:
-
1
-
2 // 直接传函数名 NonClassFunction
-
3 set_error_handler('function_name');
-
4
-
5 // 传 class_name && function_name
-
6 set_error_handler(array('class_name', 'function_name'));
-
7
2:register_shutdown_function()
捕获PHP的错误:Fatal Error、Parse Error等,这个方法是PHP脚本执行结束前最后一个调用的函数,比如脚本错误、die()、exit、异常、正常结束都会调用,多么牛逼的一个函数啊!通过这个函数就可以在脚本结束前判断这次执行是否有错误产生,这时就要借助于一个函数:error_get_last();这个函数可以拿到本次执行产生的所有错误。error_get_last();返回的信息:
[type] - 错误类型
[message] - 错误消息
[file] - 发生错误所在的文件
[line] - 发生错误所在的行
-
1
-
2 register_shutdown_function('zyfshutdownfunc');
-
3 function zyfshutdownfunc()
-
4 {
-
5 if ($error = error_get_last()) {
-
6 var_dump('<b>register_shutdown_function: Type:' . $error['type'] . ' Msg: ' . $error['message'] . ' in ' . $error['file'] . ' on line ' . $error['line'] . '</b>');
-
7 }
-
8 }
-
9
通过这种方法就可以巧妙的打印出程序结束前所有的错误信息。但是我在测试的时候我发现并不是所有的错误终止后都会调用这个函数,可以看下面的一个测试文件,内容是:
-
1
-
2 register_shutdown_function('zyfshutdownfunc');
-
3 function zyfshutdownfunc()
-
4 {
-
5 if ($error = error_get_last()) {
-
6 var_dump('<b>register_shutdown_function: Type:' . $error['type'] . ' Msg: ' . $error['message'] . ' in ' . $error['file'] . ' on line ' . $error['line'] . '</b>');
-
7 }
-
8 }
-
9 var_dump(23+-+); //此处语法错误
-
10
自己可以试一下,你可以看到根本就不会触发zyfshutdownfunc()函数,其实这是一个语法错误,直接报了一个:
-
1
-
2 Parse error: syntax error, unexpected ')' in /www/mytest/exception/try-catch.php on line 71
-
3
由此引出一个奇葩的问题:问什么不能触发,为什么框架中是可以的?其实原因很简单,只在parse-time出错时是不会调用本函数的。只有在run-time出错的时候,才会调用本函数,我的理解是语法检查器前没有执行register_shutdown_function()去把需要注册的函数放到调用的堆栈中,所以就根本不会运行。那框架中为什么任何错误都能进入到register_shutdown_function()中呢,其实在框架中一般会有统一的入口index.php,然后每个类库文件都会通过include ** 的方式加载到index.php中,相当与所有的程序都会在index.php中聚集,同样,你写的具有语法错误的文件也会被引入到入口文件中,这样的话,调用框架,执行index.php,index.php本身并没有语法错误,也就不会产生parse-time错误,而是 include 文件出错了,是run-time的时候出错了,所以框架执行完之后就会触发register_shutdown_function();
所以现在可是试一下这个写法,这样就会触发zyfshutdownfunc()回调了:
1 a.php文件 2 <?php 3 // 模拟语法错误 4 var_dump(23+-+); 5 ?> 6 7 b.php文件 8 <?php 9 register_shutdown_function('zyfshutdownfunc'); 10 function zyfshutdownfunc() 11 { 12 if ($error = error_get_last()) { 13 var_dump('<b>register_shutdown_function: Type:' . $error['type'] . ' Msg: ' . $error['message'] . ' in ' . $error['file'] . ' on line ' . $error['line'] . '</b>'); 14 } 15 } 16 require 'a.php';