【问题标题】:How to return an HTTP 500 code on any error, no matter what无论如何,如何在任何错误上返回 HTTP 500 代码
【发布时间】:2023-12-15 17:24:01
【问题描述】:

我正在用 PHP 编写一个身份验证脚本,作为 API 调用,否则需要返回 200only in the case that it approves the request, and403(Forbidden) or500`。

我遇到的问题是 php 在错误情况下返回200,而是将错误输出为 html。除非我自己明确返回 HTTP 200 或 HTTP 403,否则我如何绝对确保 php 将返回 HTTP 500 代码?换句话说,我想将任何和所有警告或错误条件都变成500s,没有例外,因此默认情况是拒绝身份验证请求,而例外情况是使用200 代码批准它。

我曾摆弄过set_error_handler()error_reporting(),但到目前为止还没有运气。例如,如果代码在我发送HTTP响应代码之前输出了一些东西,PHP自然会报告你输出任何东西后不能修改头信息。但是,PHP 将其报告为 200 响应代码,其中包含解释问题的 html。我什至需要将这种东西变成500 代码。

这在 PHP 中可行吗?还是我需要在更高级别上执行此操作,例如以某种方式使用mod_rewrite?如果是这样的话,知道我是如何设置的吗?

【问题讨论】:

标签: php http response


【解决方案1】:

只需发送状态码作为响应header()

header('HTTP/1.1 500 Internal Server Error');

请记住,发送此内容时,不得在其之前有任何输出。这意味着没有 echo 调用,也没有 HTML 或空格。

【讨论】:

  • 另外请记住,如果作为 CGI 或在 IIS 下运行,这将不起作用。
  • 谢谢 - 我知道如何发送响应代码,并且我知道不要在它之前发送输出,正如我在问题中提到的那样。我的问题是如何防止 PHP 在出现错误的情况下发送 200 响应代码,错误为 html。
  • 发送它然后输出错误信息?发送状态标头告诉 PHP 覆盖默认的 200 OK 响应代码。
  • BoltClock:如果出现未处理的异常,您如何知道要发送什么标头?
  • 很好的解决方案,尽管现在所有的孩子都在使用http_response_code(500); 来设置标题。
【解决方案2】:

我检查了the PHP docs for header(),它比我做的更简单——如果第二个参数为真,它将替换一个类似的标题。默认为真。所以正确的行为是header('HTTP/1.1 403 Forbidden');,然后做认证逻辑,如果认证了,做header('HTTP/1.1 200 OK')。它将替换 403 响应,并保证 403 是默认值。

【讨论】:

    【解决方案3】:

    从 PHP 5.4.0 开始有一个专门的函数:

    <?php http_response_code( 500 ); ?>
    

    只需确保在任何其他输出之前调用它即可。

    参考:

    【讨论】:

    • 虽然很有趣,但这并不能阻止 php 在遇到错误时返回 200 OK。
    • 当然,这不能代替错误handling,而是错误reporting
    【解决方案4】:

    在 set_error_handler() 的 php 页面上,您可以找到 smp 在 ncoastsoft dot com 于 2003 年 9 月 8 日 10:28 发布的评论,该评论解释了如何捕获致命错误(您通常无法通过自定义捕获错误处理程序。我根据您的需要更改了代码:

    error_reporting(E_ALL);
    ini_set('display_errors', 'on');
    
    function fatal_error_handler($buffer) {
        header('HTTP/1.1 500 Internal Server Error');
        exit(0);
    }
    
    function handle_error ($errno, $errstr, $errfile, $errline){
        header('HTTP/1.1 500 Internal Server Error');
        exit(0);
    }
    
    ob_start("fatal_error_handler");
    set_error_handler("handle_error");
    
    //would normally cause a fatal error, but instead our output handler will be called allowing us to handle the error.
    somefunction();
    ob_end_flush();
    

    这会捕获不存在函数的致命错误。然后它会返回 500 并停止脚本其余部分的执行。

    【讨论】:

    • 它将捕获任何错误但解析错误。 – 此外,它会隐藏错误跟踪,因此您也可以禁用 display_errors 以获得相同的功能。
    • @ThomasAhle 您可以在设置标题后自己输出堆栈跟踪
    【解决方案5】:
    header($_SERVER['SERVER_PROTOCOL'] . ' 403 Forbidden');
    

    您不应该使用 500,这表示内部服务器错误。

    此(和其他标头)应在任何输出之前发送,除非您启用了输出缓冲。

    【讨论】:

    • 谢谢,但这不是我的问题。我知道如何发送响应代码。如何防止PHP在出错的情况下发送200代码?
    • @Jake 如果发送 403 响应,它不会发送 200。我错过了什么吗?
    • 问题是如果它在我知道是否发送 403 0r 200 之前遇到错误情况,它会发送带有错误的 200。我想要相反的行为 - 我希望出现错误时的默认值是 403 或 500 或几乎任何 200 以外的值,因此只有我发送 200 响应代码。我会立即尝试编写 403 代码,如果成功,然后用 200 覆盖它。我不知道在这种情况下应该是什么行为。有人知道吗?它会正确覆盖 403 吗?
    【解决方案6】:

    好奇你是否曾想出如何让 PHP 在解析错误时返回 500...我有同样的需求...API 正在发布到我们的应用程序,并且只有在所有内容都得到正确处理的情况下才期望 200...

    在解析错误的情况下,PHP 返回错误 200,我已经使用了这两个函数:

    register_shutdown_function() set_error_handler()

    当代码中发生“解析/语法”错误时,这些不会受到影响......

    所以这是一个低级 PHP 函数,必须在 PHP.INI 或其他地方设置...我使用的是 PHP 5.3.10...

    【讨论】:

      【解决方案7】:

      使用输出缓冲允许您在写入页面正文后修改标题。您可以在ini file 中进行设置,而不是更新每个脚本。

      (请注意,如果您显式刷新输出缓冲区,header() 调用仍然会失败)

      C.

      【讨论】:

        最近更新 更多