@ error suppression operator和set_error_handler

Rok*_*alj 17 php logging error-reporting operator-keyword

我遵循良好的编程习惯,我将PHP错误记录到文件而不是将其显示给用户.我用set_error_handler()它.

现在问题.例如,我有一个地方:

@file_exists('/some/file/that/is/outside/openbasedir.txt');
Run Code Online (Sandbox Code Playgroud)

但是,尽管有错误抑制操作符,错误消息仍会记录.我不希望这样.我希望抑制错误不要传递给我的错误处理程序.

Arn*_*anc 29

@运营商临时将使用error_reporting为0,这样你就可以测试你的错误处理程序使用error_reporting的价值:

if (ini_get('error_reporting') == 0) {
    return;
}
Run Code Online (Sandbox Code Playgroud)

或者甚至更好,只记录error_reporting中的错误类型:

$error_reporting = ini_get('error_reporting');

if ( !($error_reporting & $errno) ) {
    return;
}
Run Code Online (Sandbox Code Playgroud)

另请查看log_errorserror_log选项,以自动将错误记录到文件或syslog中.

  • 不适用于我(PHP7),但这样做:if(error_reporting()== 0){return; } (5认同)
  • `ini_get()` 在 PHP 8 上也不适合我。这做到了: `if ( !(error_reporting() & $errno) )` (3认同)

Sim*_*ckx 8

也适用于 PHP 7 的解决方案

根据 PHP 文档:

如果您使用 set_error_handler() 设置了自定义错误处理函数,那么它仍然会被调用,但是这个自定义错误处理函数可以(并且应该)调用 error_reporting() ,当触发错误的调用之前是 @ 时,它将返回 0 .

来源:http : //php.net/manual/en/language.operators.errorcontrol.php

因此,您可以在错误处理程序中使用以下代码:

function exception_error_handler($errno, $errstr, $errfile, $errline ) {
    if (error_reporting() == 0) {
        /// @ sign temporary disabled error reporting
        return;
    }

    throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
}

set_error_handler("exception_error_handler");
Run Code Online (Sandbox Code Playgroud)


Dim*_* L. 5

PHP8 行为已更改,检查error_reporting() == 0错误处理程序不再有效。PHP8中检查@抑制的错误的方法如下:

function errorHandler($err_severity, $err_msg, $err_file, $err_line)
{
    // Skip errors suppressed by @
    if (!(error_reporting() & $err_severity)) {
        return true;
    }

    // Error handling here
    return false;
}
Run Code Online (Sandbox Code Playgroud)