聊聊在PHP中如何处理错误

前言

在PHP中,如果代码发生错误,PHP默认会把错误信息直接输出到页面,如下图:
在这里插入图片描述

这样会将敏感信息暴露给用户,十分不安全,因此通常会使用set_error_handler设置一个自定义的错误处理函数,在此函数中我们可以对发生的错误做出统一处理,例如将错误信息记录到日志、结束脚本运行等等:

set_error_handler(function($errno, $errstr, $errfile, $errline) {
    $errInfo = [$errno, $errstr, $errfile, $errline];
    // 记录错误信息到日志文件
    file_put_contents('/path/to/file.log', json_encode($errInfo), FILE_APPEND);
    // 结束脚本运行
    exit();
});

// 使用一个未定义的变量,会触发E_NOTICE级别错误
echo $bar;

设置了错误处理函数后,PHP会将错误交由此函数处理,而且这些错误都不会显示在页面上,即使error_reporting设置为了E_ALL

注1:除了设置error_handler函数这种方法外,还可以通过配置php.ini的display_erros、log_errors、error_log参数来屏蔽网页中显示的错误信息。

注2:如果在代码中使用了 @ 错误抑制符,发生的错误仍然会被传递给error_handler函数处理,且在PHP 8(不含)之前的版本中,使用了 @ 抑制符后,在error_handler中调用error_reporting()函数获取到的值将会是0

注3:在error_handler中返回false会重新把此错误抛回给PHP标准错误处理程序做处理

但是这样就足够了吗?答案是不足够。因为有部分错误PHP并不会交给error_handler函数处理,例如E_ERROR级别的错误,下面见一个例子:

set_error_handler(function($errno, $errstr, $errfile, $errline) {
    echo "Caught an error in error handler function!";
    exit();
});

// 调用未定义的函数,会触发E_ERROR级别错误
call_undefined_func();

执行上述代码后:
在这里插入图片描述
因为E_ERROR级别的错误没有交给error_handler函数处理,所以PHP又把它显示在了页面上,那这时候可以怎样处理呢?
如果你使用的是PHP 5.x版本,那么可以结合使用register_shutdown_functionerror_get_last函数来捕获这个错误,但这函数只能捕获错误,并不能把错误信息从页面上隐藏,我们可以使用@错误抑制符或关闭error_reportingini_set('display_errors', 'Off')来隐藏错误信息,代码如下:

register_shutdown_function(function() {
    $lastErr = error_get_last();
    if ($lastErr !== null) {
        echo "Caught error in shutdown function!";
        exit();
    }

});

// 方法1:关闭error_reporting
error_reporting(0);

// 方法2:关闭display_errors
// ini_set('display_errors', 'Off');

// 调用未定义的函数,会触发E_ERROR级别错误
call_undefined_func();

如果你使用的是PHP 7.x版本,那么可以使用set_exception_handler来捕获E_ERROR错误:

set_exception_handler(function($e) {
    echo "Caught error in exception handler function!";
    exit();
});

// 调用未定义的函数,会触发E_ERROR级别错误
call_undefined_func();

结论

建议同时set_error_handlerset_exception_handlerregister_shutdown_function来捕获错误和异常。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值