php 遇到致命异常时如何让php返回500?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1555862/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I get php to return 500 upon encountering a fatal exception?
提问by Mike
PHP fatal errors come back as status code 200 to the HTTP client. How can I make it return a status code 500 (Internal server error)?
PHP 致命错误作为状态代码 200 返回给 HTTP 客户端。如何让它返回状态代码 500(内部服务器错误)?
回答by Chris Jester-Young
header("HTTP/1.1 500 Internal Server Error");
回答by fuyi
This is exactly the problem I had yesterday and I found solution as follows:
这正是我昨天遇到的问题,我找到了如下解决方案:
1) first of all, you need to catch PHP fatal errors, which is error type E_ERROR. when this error occurs, script will be stored the error and terminate execution. you can get the stored error by calling function error_get_last().
1)首先,你需要捕捉PHP致命错误,即错误类型E_ERROR。发生此错误时,脚本将存储错误并终止执行。您可以通过调用函数 error_get_last() 获取存储的错误。
2) before script terminated, a callback function register_shutdown_function() will always be called. so you need to register a error handler by this function to do what you want, in this case, return header 500 and a customized internal error page (optional).
2) 在脚本终止之前,回调函数 register_shutdown_function() 将始终被调用。所以你需要通过这个函数注册一个错误处理程序来做你想做的事情,在这种情况下,返回标题 500 和一个自定义的内部错误页面(可选)。
function my_error_handler()
{
$last_error = error_get_last();
if ($last_error && $last_error['type']==E_ERROR)
{
header("HTTP/1.1 500 Internal Server Error");
echo '...';//html for 500 page
}
}
register_shutdown_function('my_error_handler');
Note: if you want to catch custom error type, which start with E_USER*, you can use function set_error_handler() to register error handler and trigger error by function trigger_error, however, this error handler can not handle E_ERROR error type. see explanation on php.net about error handler
注意:如果要捕获以E_USER*开头的自定义错误类型,可以使用函数set_error_handler()注册错误处理程序并通过函数trigger_error触发错误,但是该错误处理程序无法处理E_ERROR错误类型。请参阅 php.net 上有关错误处理程序的说明
回答by Matti Haavikko
I have used "set_exception_handler" to handle uncaught exceptions.
我使用“set_exception_handler”来处理未捕获的异常。
function handleException($ex) {
error_log("Uncaught exception class=" . get_class($ex) . " message=" . $ex->getMessage() . " line=" . $ex->getLine());
ob_end_clean(); # try to purge content sent so far
header('HTTP/1.1 500 Internal Server Error');
echo 'Internal error';
}
set_exception_handler('handleException');
回答by lukyer
Standard PHP configuration doesreturn 500 when error occurs! Just make sure that your display_errors = off. You can simulate it with:
标准 PHP 配置确实在发生错误时返回 500!只需确保您的 display_errors = off。你可以模拟它:
ini_set('display_errors', 0);
noFunction();
On production display_errors directive is off by default.
在生产中 display_errors 指令默认关闭。
回答by Jonathan Hanson
It is not possible to handle PHP E_ERROR in any way according to the PHP documentation: http://www.php.net/manual/en/function.set-error-handler.php
根据 PHP 文档,不可能以任何方式处理 PHP E_ERROR:http: //www.php.net/manual/en/function.set-error-handler.php
Nor is is possible to handle "E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING, and most of E_STRICT" according to that link.
根据该链接,也无法处理“E_PARSE、E_CORE_ERROR、E_CORE_WARNING、E_COMPILE_ERROR、E_COMPILE_WARNING 和大部分 E_STRICT”。
You CAN provide a handler for the other error, warning, and notices including E_USER_ERROR, but that's really not as useful as it sounds since this error only gets thrown intentionally by the programmer with trigger_error().
您可以为包括 E_USER_ERROR 在内的其他错误、警告和通知提供处理程序,但这实际上并不像听起来那么有用,因为此错误只会由程序员通过 trigger_error() 有意抛出。
And of course you can catch any Exception (even the ones thrown by the native PHP functions).
当然,您可以捕获任何异常(甚至是由本机 PHP 函数抛出的异常)。
I agree that this is a problem. Servers should NOT return 200 OK when application code crashes and burns.
我同意这是一个问题。当应用程序代码崩溃和烧毁时,服务器不应返回 200 OK。
回答by Tiberiu-Ionu? Stan
Never forget to set header("HTTP/1.1 200 OK", true, 200);as the last line of any execution path:
永远不要忘记设置header("HTTP/1.1 200 OK", true, 200);为任何执行路径的最后一行:
//first things first:
header("HTTP/1.1 500 Internal Server Error", true, 500);
//Application code, includes, requires, etc. [...]
//somewhere something happens
//die();
throw new Exception("Uncaught exception!");
//last things last, only reached if code execution was not stopped by uncaught exception or some fatal error
header("HTTP/1.1 200 OK", true, 200);
In PHP 5.4you can replace the headerfunction above with the much better http_response_code(200)or http_response_code(500).
在PHP 5.4你可以用header更好的http_response_code(200)或http_response_code(500).
回答by Remco Nijhuis
The hard thing when dealing with fatal errors (compile errors, for example a missing semicolon) is that the script won't be executed, so it won't help to set the status code in that script. However, when you include or require a script, the calling script will be executed, regardless of errors in the included script. With this, I come to this solution:
处理致命错误(编译错误,例如缺少分号)时的困难在于脚本不会被执行,因此在该脚本中设置状态代码无济于事。但是,当您包含或需要一个脚本时,调用脚本将被执行,而不管包含的脚本中是否有错误。有了这个,我来到了这个解决方案:
rock-solid-script.php:
坚如磐石的script.php:
// minimize changes to this script to keep it rock-solid
http_response_code(500); // PHP >= 5.4
require_once("script-i-want-to-guard-for-errors.php");
script-i-want-to-guard-for-errors.php:
script-i-want-to-guard-for-errors.php:
// do all the processsing
// don't produce any output
// you might want to use output buffering
http_response_code(200); // PHP >= 5.4
// here you can produce the output
Direct your call to the rock-solid-script.php and you're ready to go.
将您的呼叫定向到坚如磐石的script.php,您就可以开始了。
I would have liked it better to set the default status code to 500 in .htaccess. That seems more elegant to me but I can't find a way to pull it off. I tried the RewriteRule R-flag, but this prevents execution of php altogether, so that's no use.
我更希望在 .htaccess 中将默认状态代码设置为 500。这对我来说似乎更优雅,但我找不到一种方法来实现它。我尝试了 RewriteRule R 标志,但这完全阻止了 php 的执行,所以没有用。
回答by Xinus
回答by Xeoncross
You would have to catch the thrown error using try/catchand then use that catch block to send a header()with the 500 error.
您必须使用try/catch 捕获抛出的错误,然后使用该 catch 块发送带有 500 错误的header()。
try {
...badcode...
throw new Exception('error');
} catch (Exception $e) {
header("Status: 500 Server Error");
var_dump($e->getMessage());
}
If the fatal exception is not surrounded by try {} catch blocks then you must register a global handler and use register_shutdown_function()to check for an error at script end.
如果致命异常没有被 try {} catch 块包围,那么您必须注册一个全局处理程序并register_shutdown_function()用于在脚本结束时检查错误。

