65

PHP 致命错误以状态码 200 的形式返回给 HTTP 客户端。如何让它返回状态码 500(内部服务器错误)?

4

10 回答 10

59
header("HTTP/1.1 500 Internal Server Error");
于 2009-10-12T17:28:13.933 回答
29

这正是我昨天遇到的问题,我找到了如下解决方案:

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 上有关错误处理程序的说明

于 2012-01-13T14:09:28.667 回答
8

发生错误时,标准 PHP 配置确实返回 500!只需确保您的 display_errors = off。你可以模拟它:

ini_set('display_errors', 0); 
noFunction();

默认情况下,在生产中 display_errors 指令是关闭的。

于 2016-04-05T13:27:58.400 回答
7

我使用“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');
于 2010-09-23T10:10:40.777 回答
4

由于 PHP >= 5.4

http_response_code(500);
echo json_encode( [ 'success' => false , 'message' => 'Crazy thing just happened!' ]);
exit();

请在之前设置httpCode echo

于 2020-06-16T05:09:44.460 回答
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。

于 2010-01-24T02:41:18.607 回答
0

处理致命错误(编译错误,例如缺少分号)时的困难在于脚本不会被执行,因此在该脚本中设置状态代码无济于事。但是,当您包含或需要脚本时,将执行调用脚本,而不管包含的脚本中是否有错误。有了这个,我得出了这个解决方案:

坚如磐石的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");

脚本-我想要保护-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

将您的电话转到rock-solid-script.php,您就可以开始了。

我希望在 .htaccess 中将默认状态代码设置为 500 会更好。这对我来说似乎更优雅,但我找不到办法把它拉下来。我尝试了 RewriteRule R-flag,但这完全阻止了 php 的执行,所以没有用。

于 2013-02-22T17:50:53.477 回答
0

您可以使用 php 错误处理

http://www.w3schools.com/php/php_error.asp

于 2009-10-12T17:28:29.300 回答
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()用于在脚本结束时检查错误。

于 2009-10-12T17:30:35.817 回答
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你可以用更好的 or 替换上面headerhttp_response_code(200)函数http_response_code(500)

于 2012-08-01T17:41:59.533 回答