PHP错误处理

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/hjue/article/details/17222979

文章转自 http://hjue.me/post/php-error-handle


程序一定会有错误的时候

天才的程序员说,我的程序绝对OK,没有错误,我从不处理错误。的确,天才程序员的程序从来没有错误,但程序只要运行,就会有错误!不管你信不信,我反正是信的。

错误不只是来自于程序逻辑,更多的来自于环境:

  • 数据库连接数太多,程序连接数据库失败
  • 网络连接故障,连接缓存服务器失败
  • Redis缓存已满,无法写入
  • 合作方接口异常,无法正常响应
    ......

太多了,变化的环境总是挑战我的想象力。

真正的程序员很重视错误处理,让程序固若金汤。真正的PHP程序员哪怕是Notice也不放过 :)

首先,要注意和错误有关的PHP配置变量。以下是PHP.ini中的默认值。

display_errors = Off
error_reporting = E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED

这是建议开发环境中设置的值:

display_errors= On
error_reporting = E_ALL

这是建议服务器环境中设置的值:

display_errors= Off
error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT

PHP中错误报告的级别

以下列出常用的错误报告的级别,所有错误报告的级别点这里

常量描述
1E_ERROR致命的运行时错误。后果是导致脚本终止不再继续运行。
2E_WARNING运行时警告 (非致命错误)。仅给出提示信息,但是脚本不会终止运行。
4E_PARSE编译时语法解析错误。解析错误仅仅由分析器产生。
8E_NOTICE运行时通知。
256E_USER_ERROR致命的用户生成的错误。这类似于程序员使用 PHP 函数 trigger_error() 设置的 E_ERROR。
512E_USER_WARNING非致命的用户生成的警告。这类似于程序员使用 PHP 函数 trigger_error() 设置的 E_WARNING。
1024E_USER_NOTICE用户生成的通知。这类似于程序员使用 PHP 函数 trigger_error() 设置的 E_NOTICE。
2048E_STRICT (integer) 启用 PHP 对代码的修改建议,以确保代码具有最佳的互操作性和向前兼容性。 
4096E_RECOVERABLE_ERROR可捕获的致命错误。类似 E_ERROR,但可被用户定义的处理程序捕获。
8192E_DEPRECATED运行时通知。启用后将会对在未来版本中可能无法正常工作的代码给出警告。
8191E_ALL所有错误和警告,除级别 E_STRICT 以外。

E_WARNING

php -r 'error_reporting(E_ERROR);include "test.php";'
//Warning: include(test.php): failed to open stream: No such file or directory in Command line code on line 1

E_NOTICE

php -r 'error_reporting(E_ERROR);echo $a[0];'
//Notice: Undefined variable: a in Command line code on line 1

E_PARSE

php -r 'error_reporting(E_ERROR);echo 0'
//Parse error: syntax error, unexpected end of file, expecting ',' or ';' in Command line code on line 1

E_USER_WARNING

php -r 'error_reporting(E_ERROR);trigger_error("Value must be 1",E_USER_WARNING);' 
//Warning: Value must be 1 in Command line code on line 1

E_USER_ERROR

php -r 'error_reporting(E_ERROR);trigger_error("Value must be 1",E_USER_ERROR);'     
//Fatal error: Value must be 1 in Command line code on line 1

E_USER_NOTICE

php -r 'error_reporting(E_ERROR);trigger_error("Value must be 1",E_USER_NOTICE);'     
//Notice: Value must be 1 in Command line code on line 1

E_ERROR

php -r 'error_reporting(E_ERROR);$a=null;echo $a->method();'
//Fatal error: Call to a member function method() on a non-object in Command line code on line 1

php -r 'error_reporting(E_ERROR);require_once("test.php");' 
//Warning: require_once(test.php): failed to open stream: No such file or directory in Command line code on line 1
//Fatal error: require_once(): Failed opening required 'test.php' in Command line code on line 1

用set_error_handler捕获错误

set_error_handler:设置一个用户的函数来处理脚本中出现的错误。

使用set_error_handler捕获程序错误

php -r 'error_reporting(E_ERROR);
set_error_handler(function($errno, $errstr, $errfile, $errline){var_dump($errno, $errstr, $errfile, $errline);});
require("test.php");
echo "finished!";'

Php Error 1

从截图中看到,有var_dump的信息,说明set_error_handler捕获到了错误。并且没有看到我需要输出的finished!,说明程序在遇到错误终止了,没有继续运行。

set_error_handler不是万能的,也有捕获不到的时候

php -r 'error_reporting(E_ERROR);
set_error_handler(function($errno, $errstr, $errfile, $errline){var_dump($errno, $errstr, $errfile, $errline);});
$a=null;$a->method();
echo "finished!";'

Php Error 1 
截图中没有看到var_dump信息,说明set_error_handler没有捕获到错误。这时候要用register_shutdown_function+error_get_last来捕获

php -r 'error_reporting(E_ERROR);
function logerror() {if (($error = error_get_last())) {var_dump($error);}}
register_shutdown_function('logerror');
$a=null;$a->method();
echo "finished!";'

Php Error 1

错误日志集中管理

错误日志集中管理的平台很多,我们无需多造个轮子。我的选择是Sentry

Sentry是一个的错误日志服务器,可以将程序错误的详细情况集中捕获,并提供一个很漂亮的Web界面来浏览错误。 Sentry本身是用python写的,但它支持记录python、php、ruby、iOS等多种语言的错误。

展开阅读全文

没有更多推荐了,返回首页