最近项目中有一个功能需要实现:调试模式下, 将所有错误提前输出, 再输出页面内容.为实现上述功能, 需使用到Exception, Error相关Handler方法, 发现有许多坑, 故写此文与大家分享.
前言 最近项目中有一个功能需要实现:调试模式下, 将所有错误提前输出, 再输出页面内容. 为实现上述功能, 需使用到Exception, Error相关Handler方法, 发现有许多坑, 故写此文与大家分享. 推荐PHP视频教程:https://www.php.cn/course/list/29/type/2.html 主要函数 此篇文章重点关注以下几个函数 1、 2、 3、 4、 5、 以下本文中重点讲解问题列表: 1、 2、 3、 解疑: 1. link: a: 大家应该再熟悉不过了, 因此不再赘述. b: 获取最后发生的错误 通常用来获取PHP运行过程中的Fatal Error错误(PHP 5). 这两个函数在字面上关联性并不强, 但请观察以下代码及输出 <?php error_reporting(E_ALL & ~E_NOTICE); $a = $b; //E_NOTICEprint_r(error_get_last());/* output: Array ( [type] => 8 [message] => Undefined variable: b [file] => /app/t.php [line] => 3 ) */
2. link: a、 设置用户自定义的错误处理函数 通常在PHP脚本运行过程中, 出现一些非中断性错误时触发. 注意: FALSE: 标准的错误处理依然会被执行(标准错误处理根据 1、参数 2、以下级别的错误不能由用户定义的函数来处理: 3、handler被触发后, 并不会中断PHP运行. 4、
设置用户自定义的异常处理函数 注意: 注意点中2, 3项轻描淡写了一下PHP 5/PHP 7之间的不同却透露出重要的消息(坑..) 1、 2、PHP 5, PHP 7的 3、自 PHP 7 以来,大多数错误抛出 因此, PHP 5: 1、 2、 3、 PHP 7: 1、 2、 3、 3. link: 注册一个 callback ,它会在脚本执行完成或者 exit() 后被调用。 根据说明可以得出结论, 它与 <?php register_shutdown_function('shutdown_function'); unknown_function();function shutdown_function() { print_r(error_get_last()); }/* output:Array( [type] => 1 [message] => Uncaught Error: Call to undefined function unknown_function() in /app/t.php:3Stack trace:#0 {main} thrown [file] => /app/t.php [line] => 3) */ 然而随着PHP 7的到来, Error已经可以被 实例 前言中的需求: 调试模式下, 将所有错误提前输出, 再输出页面内容. <?php/* 要求: 将所有异常打印在屏幕最上方 *//* Fatal Error 中断脚本 -> shutdown_handler *///设置错误级别define("END_ERRORS", '--END ERRORS--' . PHP_EOL . PHP_EOL); ini_set('display_errors', true); ini_set('error_reporting', E_ALL & ~E_DEPRECATED); set_error_handler('usr_err_handler', error_reporting()); //注册错误处理函数set_exception_handler('usr_ex_handler'); //注册异常处理函数register_shutdown_function('shutdown_handler'); //注册会在php中止时执行的函数$global_errors = []; //用于记录所有错误$errnos = [ //错误级别 0 => 'ERROR',//PHP7 ERROR的CODE 1 => 'E_ERROR',//FATAL ERROR(PHP5), E_ERROR 2 => 'E_WARNING', 4 => 'E_PARSE', 8 => 'E_NOTICE', 16 => 'E_CORE_ERROR', 32 => 'E_CORE_WARNING', 64 => 'E_COMPILE_ERROR', 128 => 'E_COMPILE_WARNING', 256 => 'E_USER_ERROR', 512 => 'E_USER_WARNING', 1024 => 'E_USER_NOTICE', 2048 => 'E_STRICT', 4096 => 'E_RECOVERABLE_ERROR', 8192 => 'E_DEPRECATED', 16384 => 'E_USER_DEPRECATED', 30719 => 'E_ALL', ];function reset_errors(){ global $global_errors; $global_errors = []; }function get_errnostr($errno){ global $errnos; return $errnos[$errno]; }function set_errnos($errno, $errstr){ global $global_errors; $global_errors[] = [ 'errno' => $errno, 'errnostr' => get_errnostr($errno), 'errstr' => $errstr, ]; }function print_errors($prefix){ global $global_errors; foreach ($global_errors as $err) {//由于handler中依然有可能有error 因此放最后 printf("[%s]: %s, %d, %s\n", $prefix, $err['errnostr'], $err['errno'], $err['errstr']); } }//用户异常处理函数 (进来就中断脚本) PHP5只有Exception进来 PHP7Error和Exception//PHP7中 void handler (Throwable $ex) 可捕获Error和Exception两种异常, 暂不管//http://php.net/manual/en/language.errors.php7.php PHP7 Error阅读//内部如果有Error则触发Error函数, 再回到错误行继续执行function usr_ex_handler($ex){ $content = ob_get_clean(); //让Exception/Error提前展示 print_errors('EX ERROR'); reset_errors(); $errnostr = get_errnostr($ex->getCode()); $errno = $ex->getCode(); $errstr = $ex->getMessage(); if ($ex instanceof Exception) { printf("[EXCEPTION]: %s, %d, %s\n", $errnostr, $errno, $errstr); } else {//针对PHP7 $ex instanceof Error printf("[EX FATAL ERROR]: %s, %d, %s\n", $errnostr, $errno, $errstr); } //由于handler中依然有可能有error 因此放最后 print_errors('EX ERROR'); reset_errors(); echo END_ERRORS; echo $content; return; }//用户错误处理函数//E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING不能被用户处理function usr_err_handler($errno, $errstr, $errfile, $errline, $errcontext){ set_errnos($errno, $errstr); return true; //如果函数返回 FALSE,标准错误处理处理程序将会继续调用。}//用户PHP终止函数function shutdown_handler(){ $content = ob_get_clean(); //让Exception/Error提前展示 $err = error_get_last();//检查一下是否有遗漏掉的错误 php5 fatal error if ($err['type'] & error_reporting()) { set_errnos($err['type'], $err['message']); } print_errors('ST ERROR'); reset_errors(); echo $content; } ob_start();echo 'Main function...', PHP_EOL;//搞事情//throw new Exception('这是一个异常');trigger_error('这是一个用户error');//E_USER_NOTICEif (version_compare(PHP_VERSION, '7.0.0') >= 0) { mcrypt_encrypt();//E_WARNING, E_DEPRECATED} else { mysql(); } unknown_function(); //fatal error$content = ob_get_clean();//优先输出错误print_errors('MA ERROR');if (!empty($global_errors)) { echo END_ERRORS; } reset_errors();//输出正文内容echo $content; 以上就是全部内容了,更多相关问题请访问PHP中文网:https://www.php.cn/ 以上就是关于PHP中Exception、Error Handler的细节以及实例详解的详细内容,更多请关注模板之家(www.mb5.com.cn)其它相关文章! |