Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/282.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php @错误抑制运算符和设置错误处理程序_Php_Logging_Operator Keyword_Error Reporting - Fatal编程技术网

Php @错误抑制运算符和设置错误处理程序

Php @错误抑制运算符和设置错误处理程序,php,logging,operator-keyword,error-reporting,Php,Logging,Operator Keyword,Error Reporting,我遵循良好的编程实践,并将PHP错误记录到文件中,而不是显示给用户。我使用set\u error\u handler()来实现这一点 现在问题来了。例如,我在某个地方: @file_exists('/some/file/that/is/outside/openbasedir.txt'); 但是,尽管使用了错误抑制操作符,错误消息仍会记录下来。我不想那样。我不希望被抑制的错误传递给我的错误处理程序。运算符将错误报告临时设置为0,以便您可以在错误处理程序中测试错误报告的值: if (ini_get

我遵循良好的编程实践,并将PHP错误记录到文件中,而不是显示给用户。我使用
set\u error\u handler()
来实现这一点

现在问题来了。例如,我在某个地方:

@file_exists('/some/file/that/is/outside/openbasedir.txt');

但是,尽管使用了错误抑制操作符,错误消息仍会记录下来。我不想那样。我不希望被抑制的错误传递给我的错误处理程序。

运算符将错误报告临时设置为0,以便您可以在错误处理程序中测试错误报告的值:

if (ini_get('error_reporting') == 0) {
    return;
}
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");
或者更好,只记录错误报告中的错误类型:

$error_reporting = ini_get('error_reporting');

if ( !($error_reporting & $errno) ) {
    return;
}


还可以查看用于自动将错误记录到文件或系统日志的和选项。

您实际上应该避免使用
@
运算符。首先,它是缓慢的,我甚至认为它是有害的

您应该在
php.ini
文件中有两行:

error_repoting = E_ALL | E_STRICT
display_errors = Off
。。。或者,如果您无权访问php.ini文件,则应在index.php(或任何其他引导文件)顶部添加:

error_reporting( E_ALL | E_STRICT );
ini_set('display_errors', 0);

也适用于PHP7的解决方案

根据PHP文档:

如果已使用set_error_handler()设置了自定义错误处理程序函数,则仍将调用该函数,但此自定义错误处理程序可以(并且应该)调用error_reporting(),当触发错误的调用前面有@时,该函数将返回0

资料来源:

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

if (ini_get('error_reporting') == 0) {
    return;
}
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");

避免使用
@
。这是一个好的迹象,你做错了什么,不想改正它。但是,会调用errorhandler回调,即使语句本身通过
@
被“静音”。我完全同意KingCrunch,隐藏错误确实是
糟糕的做法
,您应该停止这样做。它们不是错误,而是通知。您考虑使用
isset()
测试您的局部变量告诉我,你肯定做错了什么:初始化你的局部变量<代码>警告:文件\u exists():打开\u basedir限制生效。文件(/some/path)不在允许的路径范围内:,如果您知道如何在没有@operator的情况下避免此警告,请提供帮助。因此,基本上您是说@temporary将error_reporting设置为零?对我来说不起作用(PHP7),但这样做了:if(error_reporting()==0){return;}我没有投反对票,但仅仅说避免使用并不能回答这个问题。PHP有时抛出可以捕获的异常,有时显示无法捕获的愚蠢通知。在这种情况下,关闭整个应用程序的错误不是一个合理的解决方案。在现场对它们进行沉默也不是很理想,但稍微好一点(特别是对于像file_exists或file_get_contents这样的情况,如果出现错误,它们已经返回false,因此您不需要通知)。理想情况下,PHP不会以报告错误的方式被破坏,但既然是这样,我们就需要处理它。您应该避免使用@operator,但有时您需要使用使用它们的库。@SimonBackx packagist站点上并不缺少库。你可能会找到一个更好的。不再是2011年了:DA后续问题:@符号暂时将错误报告设置为0,因此似乎无法从错误处理程序中确定警告是否由带有@前缀的代码触发,或者系统上是否禁用了错误报告。不过,我希望能够做到这一点,因为在我的案例中,尊重@是有意义的,但不尊重一般的错误报告设置。是否有一些解决方法?您可以在代码开头设置一个变量,并使用该变量在上面的
/@符号临时禁用错误报告中进行区分。另一个选项是使用
ini\u get('error\u reporting')
检查ini文件,但只有在您调整了配置文件中的错误报告后,该选项才会起作用。