如何让 PHP 在出现任何错误情况时自动将 HTTP 状态码设置为 500?(包括用户无法处理的)

如何让 PHP 在出现任何错误情况时自动将 HTTP 状态码设置为 500?(包括用户无法处理的)

问题描述:

我使用 PHP 5.3.2 运行 Apache 2.2.15,禁用display_errors",禁用display_startup_errors",启用log_errors".

I am running Apache 2.2.15 with PHP 5.3.2, 'display_errors' disabled, 'display_startup_errors' disabled, 'log_errors' enabled.

在我的设置中(所以我认为这是一种规范),PHP 会因致命错误而中止,这很好,并且将 HTTP 状态代码设置为 500.致命错误包括 E_ERROR、E_PARSE、E_CORE_ERROR、E_COMPILE_ERROR、E_USER_ERROR 以及可能的 E_RECOVERABLE_ERROR(无法自己触发,因此无法轻松检查会发生什么).我认为它确实将代码设置为 500 是一个好主意,因为我认为这是正确的做法 - 显然,如果您的脚本包含语法错误和/或无法在运行时执行应执行的操作,则是服务器错误,如果我们考虑服务器的 PHP 部分.

At my setup (so I consider it a norm), PHP aborts on fatal errors, which is good, and sets HTTP status code to 500. Fatal errors include E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR and, probably, E_RECOVERABLE_ERROR (cannot trigger it myself, so can't easily check what happens). I think it is a good idea that it does set the code to 500, because I think it is the right thing to do - obviously if your script contains syntax errors and/or fails to do what is supposed to do at runtime, it is a server error, if we consider PHP part of the server.

现在,这是重要的部分:

无论如何,我现在已经安装了 XDebug 以更好地跟踪错误,但是我现在可以看到,无论错误如何,即使脚本像以前一样因致命错误而中止,HTTP 状态代码始终为 200.这打破了我通过 HTTP 与 Apache/PHP对话"的客户端:|

Anyway, I have now installed XDebug to track errors better, but I can see that now, no matter the error, even though the script aborts as before on fatal errors, the HTTP status code is always 200. This breaks my client that 'talks' to Apache/PHP via HTTP :|

此外,将 display_errors 设置为 On/1,使 PHP 不再将 HTTP 状态代码设置为 500,并且表现出与上述 XDebug 完全相同的行为.

Also, setting display_errors to On/1, makes PHP no longer set HTTP status code to 500 and exhibits exactly the same behavior as with XDebug above.

我在这里非常依赖可靠的状态代码行为,这一切让我相信这是某种侥幸或像天气一样的随机......还是我错过了什么?

I am very much dependent on reliable status code behavior here, and this all leads me to believe it's some kind of fluke or random like weather.. or am I missing something?

更新

有一篇博客文章概述了这个问题:http://talideon.com/weblog/2008/02/php-errors.cfm

There is a blog post which oulines the issue: http://talideon.com/weblog/2008/02/php-errors.cfm

就我而言,我已禁用 XDebug,因为它首先是导致不良行为的原因.无论如何,我只将它用于堆栈跟踪,现在使用自定义错误处理程序代替.此外,链接的文章来自 2008 年,显然 PHP 确实这些天自动将 HTTP 状态代码设置为 500.它在这里这样做.当然没有 XDebug.

For my part, I have disabled XDebug, seeing as it is what causes the bad behavior in the first place. I only used it for stack tracing anyway, and now use a custom error handler for that instead. Also, the linked article is from 2008, apparently PHP does set HTTP status code to 500 automatically these days. It does so here. Without XDebug, of course.

我假设您正在使用自定义错误处理程序来发出 500.

I assume you are using a custom error handler to emit the 500.

我不太了解 XDebug,但根据这篇文章,它注册了它自己的错误处理程序,可能会在此过程中覆盖您的错误处理程序:

I don't know XDebug that well, but according to this article, it registers its own error handler, probably overriding yours in the process:

请注意,如果您使用 register_error_handler() 定义自定义错误处理程序,则 xdebug 的扩展错误显示将不起作用.这是因为 xdebug 在内部使用相同的机制.如果您的脚本使用自定义错误处理程序,您仍然可以使用函数 xdebug_get_function_stack() 在自定义错误处理程序中输出堆栈跟踪.

Please note that the extended error display of xdebug does not work if you define a custom error handler using register_error_handler(). This is because xdebug internally uses the same mechanism. Should your scripts use a custom error handler, you can still use the function xdebug_get_function_stack() to output the stack trace in your custom error handler.

但是,对于生产用途,无论如何您都不会激活 XDebug,对吗?

However, for production use, you are not going to activate XDebug anyway, are you?

至于为什么激活display_errors()时输出200,我不明白.你可以发布你的自定义错误处理函数来看看吗?

As for why a 200 is output when you activate display_errors(), that I don't understand. Can you post your custom error handler function to look at?