gpt4 book ai didi

php - 使用自定义关闭处理程序时防止 PHP fatal error 回溯输出

转载 作者:可可西里 更新时间:2023-10-31 22:49:43 25 4
gpt4 key购买 nike

在我对处理 PHP 错误的理解中一定遗漏了一些东西,特别是抑制它们的输出。当发生 fatal error 时,我希望我的关闭处理函数能够优雅地处理它并终止脚本执行。这按预期工作。 但是,我似乎无法阻止 PHP 输出有关 fatal error 的信息。

我的 php.ini 文件包含以下指令:

error_reporting = E_ALL | E_STRICT
display_errors = Off

我将 error_reporting 设置为报告所有内容,并使用自定义错误处理程序来抛出异常。我的期望是 display_errors = Off 将阻止显示任何错误消息。

无论如何,当发生 fatal error 时,自定义错误处理程序将被绕过(因为脚本执行会立即停止)并执行关闭处理程序。

现在,我的简化代码:

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

function shutdown_handler()
{
$err = error_get_last();
$fatal = array(E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR);
if ($err && in_array($err['type'], $fatal)) {
echo "\n\ntest fatal error output\n\n";
}
exit();
}

register_shutdown_function('shutdown_handler');

为了测试它,我生成了一个“Allowed memory size exhausted” fatal error ,如下所示:

// max out available memory
$data = '';
while(true) {
$data .= str_repeat('#', PHP_INT_MAX);
}

因为我有 display_errors = Off 我希望这只会产生以下输出(根据关闭处理程序):

test fatal error output

但是我继续收到:

PHP Fatal error:  Allowed memory size of 134217728 bytes exhausted (tried to allocate 2147483648 bytes) in /home/daniel/mydev/php/test0.php on line 24
PHP Stack trace:
PHP 1. {main}() /home/daniel/mydev/php/test0.php:0
PHP 2. str_repeat() /home/daniel/mydev/php/test0.php:24

test fatal error output

我遗漏了什么会阻止输出此错误跟踪?


结论

正如@Cthos 明智地指出的那样,“E_ERROR 和 display_errors 不能很好地结合在一起。”

这也是 E_PARSE 的情况(我假设 E_CORE_ERROR/E_COMPILE_ERROR,但我没有破坏我的 PHP 安装来测试它)。我想在这些情况下 PHP 会强制将错误回溯到 STDOUT 是有道理的,因为如果不这样做,您可能永远不知道事情是否/为什么会出错。

所以在这种情况下的解决方案是:

  1. 正如@Cthos 建议的那样,在 php.ini 中静音 E_ERROR 通知:error_reporting = (E_ALL & ~ E_ERROR) 或在运行时使用 error_reporting(E_ALL & ~ E_ERROR);
  2. 更新关闭处理程序以检查最后一个错误是否为 E_ERROR 类型,如果是则执行适当的操作。

至于其他 fatal error ,如 E_PARSE、E_CORE_ERROR 等,您只需确保您的代码正确并且您的 PHP 可以正常工作。如果您尝试消除 E_PARSE 错误并在您的关闭函数中处理它们,它将不起作用,因为解析错误会阻止 PHP 走那么远。

因此,更新/工作的关闭处理程序如下所示:

error_reporting(E_ALL & ~ E_ERROR);

function shutdown_handler()
{
$err = error_get_last();
if ($err && $err['type'] == E_ERROR) {
$msg = 'PHP Fatal Error: '.$err['message'].' in '.$err['file'].
' on line '.$err['line'];
echo $msg, PHP_EOL;
}
exit();
}

最佳答案

不需要的错误信息是由于错误记录配置(log_errorserror_log)引起的,并且完全独立于display_errors 配置。从命令行运行脚本时,默认的 php.ini 配置将错误详细信息记录到 stderr。在 Apache 下,它们出现在 /etc/httpd/logs/error_log 中.

查看 php_error_cb PHP 源代码的 main.c 中的函数。特别是,第 1056 行清楚地表明任何格式为“PHP %s: %s in %s on line %d”的消息都是由于错误日志记录配置(错误信息由于 display_errors 将没有“PHP:”前缀)。

关于php - 使用自定义关闭处理程序时防止 PHP fatal error 回溯输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8526039/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com