PHP致命错误作为状态代码200返回到HTTP客户端。如何让它返回状态代码500(内部服务器错误)?
答案 0 :(得分:49)
header("HTTP/1.1 500 Internal Server Error");
答案 1 :(得分:23)
这正是我昨天遇到的问题,我发现解决方案如下:
1)首先,您需要捕获PHP致命错误,这是错误类型E_ERROR。发生此错误时,脚本将存储错误并终止执行。您可以通过调用函数error_get_last()来获取存储的错误。
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');
注意:如果要捕获以E_USER *开头的自定义错误类型,可以使用函数set_error_handler()来注册错误处理程序并通过函数trigger_error触发错误,但是,此错误处理程序无法处理E_ERROR错误类型。请参阅php.net关于error handler
的解释答案 2 :(得分:6)
我使用“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');
答案 3 :(得分:3)
根据PHP文档,无法以任何方式处理PHP E_ERROR: http://www.php.net/manual/en/function.set-error-handler.php
根据该链接,也无法处理“E_PARSE,E_CORE_ERROR,E_CORE_WARNING,E_COMPILE_ERROR,E_COMPILE_WARNING和大部分E_STRICT”。
您可以为其他错误,警告和通知提供处理程序,包括E_USER_ERROR,但这实际上没有听起来那么有用,因为只有程序员使用trigger_error()才会故意抛出此错误。
当然,您可以捕获任何异常(甚至是本机PHP函数抛出的异常)。
我同意这是一个问题。当应用程序代码崩溃并烧毁时,服务器不应返回200 OK。
答案 4 :(得分:3)
标准PHP配置确实在发生错误时返回500!只需确保display_errors = off即可。您可以使用以下方法进行模拟:
ini_set('display_errors', 0);
noFunction();
生产时,display_errors指令默认处于关闭状态。
答案 5 :(得分:1)
处理致命错误(编译错误,例如缺少分号)时的难点是脚本不会被执行,因此在该脚本中设置状态代码无济于事。但是,当您包含或需要脚本时,无论所包含脚本中的错误如何,都将执行调用脚本。有了这个,我来到这个解决方案:
岩石固的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");
脚本-I-想到后卫换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
将你的电话指向rock-solid-script.php然后你准备好了。
我希望最好在.htaccess中将默认状态代码设置为500。这似乎对我来说更优雅,但我无法找到一种方法来实现它。我尝试了RewriteRule R-flag,但是这样可以完全阻止执行php,所以没用。
答案 6 :(得分:1)
因为PHP> = 5.4
http_response_code(500);
echo json_encode( [ 'success' => false , 'message' => 'Crazy thing just happened!' ]);
exit();
请在echo
之前设置httpCode。
答案 7 :(得分:0)
您可以使用php错误处理
答案 8 :(得分:0)
您必须使用try/catch捕获抛出的错误,然后使用该catch块发送带有500错误的header()。
try {
...badcode...
throw new Exception('error');
} catch (Exception $e) {
header("Status: 500 Server Error");
var_dump($e->getMessage());
}
如果致命异常没有被try {} catch块包围,那么你必须注册一个全局处理程序并使用register_shutdown_function()
来检查脚本端的错误。
答案 9 :(得分:0)
永远不要忘记将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);
在PHP 5.4
中,您可以使用更好的http_response_code(200)
或http_response_code(500)
替换上面的header
函数。