为什么PHP使用try/catch块却抛出致命错误并破坏HTTP500



在我的AWS日志中,我有这样的条目:

〔2019年2月6日星期三10:12:22.306730〕〔php7:error〕〔pid 28445〕〔client172.31.10.7:55646]PHP致命错误:未捕获错误:在中找不到类"comet_cache"/var/app/current/project网站wordpress/wp-content/mu-plugins/comet-cache-ec2-enabler.php:41

当某个HTTP 500请求发生时,会记录这些条目。

在检查代码后,我发现了以下内容(在提到的文件的第41行):

try {
comet_cache::clear();
} catch(Exception $e) {
// if comet cache is not activated, we want to continue anyway
}

这基本上是有道理的——似乎没有找到类,但如果是这样的话,应该继续执行。PHP为什么停止?

您没有捕获,因为您正在字符串捕获Exception,但抛出的是Error

考虑到您的错误消息,我认为您使用的是PHP>=7(您应该特别指出,从版本5到版本7,错误处理已经发生了显著的变化)。

在PHP>=7上,大多数致命错误不是通过引发错误来报告的,而是通过抛出Error对象来报告的。

所以你的陈述可以重写为:

try {
$a = new ClassNotFindable();
}
catch (Error $e) {
// do your catching
}

此外,ErrorException类都实现了Throwable接口,因此您可以直接捕获:

<?php
try {
$a = new NotFound();
}
catch (Throwable $t) {
echo "caught!n";
echo $t->getMessage(), " at ", $t->getFile(), ":", $t->getLine(), "n";
}

你可以看到它在这里工作。

这与AWS没有任何关系,只是一个PHP的东西。如果您使用的是PHP<7它仍然不会被捕获,但在这种情况下,因为常见错误不会抛出异常。

如果您使用PHP5,为了能够将错误作为异常捕获,您需要设置一个自定义的错误处理程序。手册中的例子似乎很合适:

function exception_error_handler($severidad, $mensaje, $fichero, $línea) {
if (!(error_reporting() & $severidad)) {
// Este código de error no está incluido en error_reporting
return;
}
throw new ErrorException($mensaje, 0, $severidad, $fichero, $línea);
}
set_error_handler("exception_error_handler");

相关内容

最新更新