提问人:Rok Kralj 提问时间:9/12/2011 最后编辑:CœurRok Kralj 更新时间:2/19/2023 访问量:3333
@ 错误抑制运算符和set_error_handler
@ error suppression operator and set_error_handler
问:
我遵循良好的编程实践,并将PHP错误记录到文件中,而不是将其显示给用户。我用它来。set_error_handler()
现在问题来了。例如,我在某处:
@file_exists('/some/file/that/is/outside/openbasedir.txt');
但是,尽管有错误抑制运算符,错误消息仍会记录。我不想那样。我希望禁止的错误不要传递给我的错误处理程序。
答:
这个答案适用于 PHP 7:
运算符暂时将 error_reporting 设置为 0,因此您可以在错误处理程序中测试 error_reporting 的值:@
if (error_reporting() == 0)
return;
或者更好的是,只记录error_reporting中的错误类型:
$error_reporting = error_reporting();
if ( !($error_reporting & $errno) )
return;
此外,请查看 log_errors
和 error_log
选项,用于自动将错误记录到文件或系统日志中。
评论
ini_get()
在 PHP 8 上也不适合我。这样做:if ( !(error_reporting() & $errno) )
实际上,您应该避免使用运算符。首先,它很慢,我甚至可以说它是有害的。@
你应该在文件中有两行: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);
评论
也适用于 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");
评论
// @ sign temporary disabled error reporting
ini_get('error_reporting')
从手册:
警告 在 PHP 8.0.0 之前,error_reporting() 在 自定义错误处理程序始终返回 0,如果错误被抑制 @ 运算符。从 PHP 8.0.0 开始,它返回值 E_ERROR | E_CORE_ERROR |E_COMPILE_ERROR |E_USER_ERROR |E_RECOVERABLE_ERROR | E_PARSE。
这意味着来自其他答案的解决方案将不起作用:(
恕我直言,@-operator 变得完全无法使用。
要禁用错误,您必须执行以下操作:
error_reporting(0); // disable
try {
$res = 10/0;
} catch (Throwable){
$res = false;
}
error_reporting(-1); // enable
评论
PHP8 行为已更改,签入错误处理程序不再起作用。在 PHP8 中检查使用 @ 抑制的错误的方法如下:error_reporting() == 0
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;
}
PHP8 代码 4437 用于@
function myErrorHandler(int $errno, string $errstr, ?string $errfile, ?int $errline) : void {
if (error_reporting() !== 4437)
{
......
}
}
set_error_handler("myErrorHandler", E_ALL);
评论
@
@
BAD PRACTICE
isset()
Warning: file_exists(): open_basedir restriction in effect. File(/some/path) is not within the allowed path(s):
,如果您知道如何在没有@操作员的情况下避免此警告,请协助。