小池有话说

PHP 错误处理

2014-12-03

PHP最原始的错误机制是error.

比如我们访问了一个并不存在的文件:

file_get_contents('a_file_but_not_exists.txt');

浏览器中会出现如下错误:

PHP Warning:  file_get_contents(a_file_but_not_exists.txt): failed to open stream: No such file or directory in D:\t.php on line 24

Warning: file_get_contents(a_file_but_not_exists.txt): failed to open stream: No such file or directory in D:\t.php on line 24

这就是PHP默认的错误处理机制.

所有的错误都不应该被忽略, 如果觉得错误不应该显示出来(比如在线上服务器), 可以将 display_errors 设为0.

可以通过如下方式来记录错误:

error_reporting(E_ALL);
ini_set('log_errors', 1); // 记录错误
ini_set('error_log', __DIR__.'/php_error.log'); // 错误记录文件的位置

不仅PHP自身的错误会被记录, 一旦设置了 error_log , 你就可以方便的使用 error_log 函数来记录错误了.

error_reporting 应该总是设置为 E_ALL 以便知道所有发生的错误. 网上有说性能问题的, 可能都是在facebook工作的吧. 如果不能保证正确性, 性能又有什么意义?

不要使用错误抑制 @. 性能损耗是一个方面, 主要还是这个运算符令人眼晕的性质, 你可能不知道自己是怎么死的.

入口文件应当尽量简短, 以减少调试的困难性.

debug_backtrace 可以用以获取当时的栈信息, 以便调试.

$trace = implode("\n".' <== ', array_map(function($e){
        $func = isset($e['class']) ? "$e[class]::$e[function]" : $e['function'];
        return "$e[file]:$e[line] $func";
    }, debug_backtrace()));
echo "$trace";

不要使用 trigger_error 函数, PHP Web开发用 Exception 更合适.

比如在 PDO 中, 有三种错误模式

默认是 PDO::ERRMODE_SILENT 坑! 所以, 我们还是将他设为 PDO::ERRMODE_EXCEPTION

$dbh = new PDO($dsn, $user, $password);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

json_decode 时, 可能会发生错误, 使用 json_last_error 可以获取错误. 为了严谨, 我们总是使用

function try_json_decode($str)
{
    $arr = json_decode($str, true);
    if (json_last_error()) {
        throw new Exception("json decode error", json_last_error());
    }
    return $arr;
}

error_log() 函数可以记录日志.

error_log("message");

可以记录到当前的日志的位置(具体来说, 就是error_log配置项的位置). 如果想要记录到一个指定文件

error_log("message\n", 3, 'log_file');

3 指的是类型 记录到文件, 注意一定要有换行符, error_log() 函数不会自动添加.


专辑: