【问题标题】:Force HTTP status to 500 if any errors occur in PHP file如果 PHP 文件中出现任何错误,则强制 HTTP 状态为 500
【发布时间】:2013-02-17 06:27:03
【问题描述】:

首先我使用的是 PHP 5.4.3。

我遇到的问题是,每当 PHP 文件发生错误(例如解析错误)时,它会在 HTML 中显示错误消息并且页面的 HTTP 状态将为 200

我想知道的是如何将 HTTP 状态设置为 500如果发生任何错误并且根本不显示任何错误。

请记住,我不想为每个页面显示 HTTP 状态 500,只显示少数页面。

【问题讨论】:

    标签: php


    【解决方案1】:

    您可以使用寄存器关闭功能。来源:PHP : Custom error handler - handling parse & fatal errors

    ini_set('display_errors', 0);
    
    function shutdown() {
        if (!is_null(error_get_last())) {
            http_response_code(500);
        }
    }
    register_shutdown_function('shutdown');
    

    注意,E_PARSE 错误只会在注册关闭功能后包含/需要的文件中被捕获。

    【讨论】:

    • 这段代码似乎可以工作,但正如帖子中的人所说,它不会跟踪 E_PARSE 错误。但由于我会在发布前测试页面,我认为这不会有问题。
    • 是的,我已将您的代码放在 PHP 页面上,并在其下方放置了会生成解析错误的代码。它没有按应有的方式处理它。
    【解决方案2】:

    myninjaname 的答案几乎是正确的 - 但是您不知道输出缓冲区在退出时发生了什么。此外,您的代码将始终运行完成。除了立即处理这种情况外,我还会使用输出缓冲和自定义 error_handler,保证对浏览器的响应,这也使得捕获和记录与错误相关的信息变得更加容易,因此您可以修复任何错误:

    <?php
    
    ob_start();
    
    set_error_handler('whoops');
    
    function whoops($errno, $errstr, $errfile, $errline, $errcontext)
    {
      header($_SERVER['SERVER_PROTOCOL'] . ' 500 Internal Server Error', true, 500);
      $logged="$errno: $errstr\nin $errfile at $errline\n";
      foreach($errcontext as $scoped=>$val) {
          $logged.=" $scoped = $val\n";
      }
      $logged.="Output = " . ob_get_clean() . "\n";
      // NB still buffering...
      debug_print_backtrace();
      $logged.="stack trace = " . ob_get_clean() . "\n";
      print "whoops";
      ob_end_flush();
      write_log_file($logged);
      exit;
    }
    

    您确实可以处理解析错误 - 它们发生在您编写和部署错误代码时 - 您应该知道如何在生产系统上防止这种情况发生。添加更多代码来尝试解决问题是矛盾的。

    您还应该通过在您的 ini 文件中设置 display_errors=0 来禁用错误显示(不报告)。

    更新

    我试图捕获使用自定义错误处理程序发生的任何错误,但由于某种原因,人们说它没有捕获解析错误(以及其他一些错误)。

    您不知道如何自己测试吗? IIRC 在很大程度上取决于上下文(关闭函数可以在包含的内容中捕获一些解析错误)和 PHP 的版本。但是如上所述,如果您已经到了生产系统上出现此类错误的地步,那是因为您没有正确完成工作。

    【讨论】:

    • +1 评论谁真正负责处理解析错误。输出缓冲区的好点,这确实是保证您不向用户发送输出的唯一方法。另外,根据您的回答将 display_errors 注释添加到我的回复中。
    【解决方案3】:

    您可以简单地设置响应代码:

    http_response_code(500);
    

    【讨论】:

    • 即使没有发生错误,该代码也会将 HTTP 状态设置为 500,这不是我想要的。
    • 我仍然需要一个条件,如果发生任何错误,它只会将其设置为 500。
    【解决方案4】:
    • 使用error_reporting(0) 关闭错误报告;
    • 使用header("HTTP/1.0 500 Internal Server Error"); 发送您自己的HTTP 状态代码

    参考

    【讨论】:

    • 我试图捕捉自定义错误处理程序发生的任何错误,但出于某种原因,人们说它没有捕捉到解析错误(以及其他一些错误)。我可以像你展示的那样设置标题,但我仍然需要一个条件才能做到这一点。如果发生任何错误,我仍然不知道会发生什么。
    猜你喜欢
    • 1970-01-01
    • 2021-06-17
    • 1970-01-01
    • 2011-03-05
    • 1970-01-01
    • 1970-01-01
    • 2023-03-25
    • 2021-01-07
    • 2018-03-26
    相关资源
    最近更新 更多