使用set_error_handler注册的错误处理器遇致命错误是否应终止脚本?
关于set_error_handler处理致命错误的脚本终止问题
首先明确:默认情况下,E_USER_ERROR这类致命错误会触发PHP内部错误处理流程,导致脚本终止;但如果通过set_error_handler()注册了自定义错误处理器,且处理器返回true,PHP的内部处理流程会被跳过,脚本会继续执行。
你的情况正是如此:错误处理器最后返回了true,这相当于告诉PHP“错误已处理完毕,无需后续操作”,所以即便触发了E_USER_ERROR,脚本也不会终止。
看你的处理器代码:
set_error_handler( function ($errno, $errstr, $errfile, $errline) { // error was suppressed with the @-operator if( 0 === error_reporting() ) { return false; } switch($errno) { default: LOG->error( "Unknown error type: [$errno] $errstr", [ 'file' => $errfile, '@' => $errline ] ); break; case E_USER_ERROR: // fall through case E_ERROR: // fall through case E_WARNING: // PHP Warnings are errors LOG->error( $errstr, [ 'file' => $errfile, '@' => $errline ] ); break; case E_USER_DEPRECATED: case E_DEPRECATED: LOG->error( "DEPRECATED $errstr", [ 'file' => $errfile, '@' => $errline ] ); break; case E_USER_WARNING: // fall through case E_NOTICE: // PHP Notices are warnings LOG->warning( $errstr, [ 'file' => $errfile, '@' => $errline ] ); break; case E_USER_NOTICE: LOG->notice( $errstr, [ 'file' => $errfile, '@' => $errline ] ); break; } /* Don't execute PHP internal error handler */ return true; } );
处理E_USER_ERROR和E_ERROR时,你仅做了日志记录,之后统一返回true跳过了PHP的内部处理——而脚本终止的逻辑正是PHP内部处理的一部分。
如果希望遇到这类致命错误时终止脚本,需要在对应的case分支里主动调用exit()或die():
修改后的关键分支示例:
case E_USER_ERROR: // fall through case E_ERROR: // fall through LOG->error( $errstr, [ 'file' => $errfile, '@' => $errline ] ); exit(1); // 主动终止脚本,非0状态码表示异常退出 break;
另外需要注意:并非所有致命错误都能被set_error_handler()捕获,比如内存耗尽、语法解析错误这类编译期错误,自定义处理器无法处理,会直接导致脚本终止。
内容的提问来源于stack exchange,提问作者theking2
相关产品推荐
相关产品推荐

