【问题标题】:Can you tell PHP to send headers (like 500) when an error occurs?你能告诉 PHP 在发生错误时发送标头(如 500)吗?
【发布时间】:2011-06-09 08:49:13
【问题描述】:

在我当前的项目中,我使用普通 HTTP 请求查询 PHP,但也通过 AJAX 查询 PHP,有时我返回 JSON 格式的数据,有时返回普通文本。当发生错误时,在正常请求中,您会看到错误消息并可以对其进行处理。另一方面,对于 AJAX 请求,您无法确定是否收到错误或您想要的数据,因为它不会直接显示 - 您只是遇到麻烦,因为您的应用程序将不再工作。

所以我想到了一个错误处理系统。如果发生错误,我最好的想法是发送 500“内部服务器错误”标头,因此在我的 JS 中,当我发送 AJAX-Request 时,我可以简单地检查错误并处理它。

不幸的是,PHP 本身并不会发送这种类型的标头(例如,当您遇到解析错误或代码中的某些内容出错时)。

你能:

a) 如果发生错误,告诉 PHP 发送 500 之类的标头?或者
b) 使用 set_error_handler 发送 500-header 然后调用 PHP 常规错误处理?或者
c) 发生 PHP 错误时,您能否以其他方式发送错误标头?

【问题讨论】:

  • try 一些代码,catch 错误然后使用header() 发送http响应代码。
  • @Arvin:异常不会捕获解析错误。
  • @Toma 为什么要上传和使用有语法错误的 PHP 文件?
  • 好吧,我在开发和测试时也遇到了本地错误。

标签: php error-handling


【解决方案1】:

我更喜欢使用异常来处理错误。首先,您需要安装 error-to-exception 错误处理程序(http://php.net/manual/en/class.errorexception.php,示例 1),然后将主应用程序代码包装在 try-catch 块中并发送捕获部分中的适当标题。例如:

try {
    $myApplication->run();
} catch(Exception $e) {
   // log or otherwise register the error
   header('HTTP/1.1 500 Internal Server Error');
}

不幸的是,这不适用于所谓的“致命错误”,要处理这些错误,您必须使用像这样的愚蠢技巧

ob_start();

register_shutdown_function(function() {
    $p = ob_get_contents();
    if(preg_match('~Fatal error~', $p))
        header('HTTP/1.0 500 Internal Server Error');
});

...your code... 

【讨论】:

  • 我编辑了您的 register_shutdown_function-method,这实际上就是我现在所做的(除了我不发送标题而是打印一些指示错误的 json (请参阅 Tomalak Geret'kal 的答案了解原因) )。非常感谢!
  • 嗯,我的更改不见了。我永远不会理解 stackoverflow。
【解决方案2】:

另一方面,使用 AJAX 请求 你不能确定你是否收到错误 或您想要的数据,因为它不是 直接显示——你只是遇到 麻烦,因为您的应用程序无法运行 没有了。

是的,你可以。

您的 XHR success 回调在数据传输成功时触发。给定应用层逻辑错误,该数据可能是一些错误消息。您的success 回调可以并且应该解析它从服务器获取的数据,并确定是否有错误。

所以我想到了一个 错误处理系统。我最好的主意是 发送 500“内部服务器错误” 如果发生错误,请标头,所以在我的 JS,当我发送 AJAX-Request 时,我可以 只需以这种方式检查错误,然后 处理它。

当您的网络服务器出现内部错误时,会生成“内部服务器错误”。您的网络服务器内部没有错误;您的应用程序中有逻辑错误。因此手动调用这样的状态码是不合适的。

不幸的是 PHP 没有发送那个 一种标题(比如当你有一个 解析错误或代码中的某些内容 出错了)。

出于上述充分理由。有不同 类型的错误,PHP/应用程序错误不会阻止网络服务器完成其工作。 HTTP 请求仍然成功(它可能不包含您希望的信息)。

考虑一个登录表单。当您尝试登录 Facebook 但不小心输入了错误的密码时,您会收到 500 Internal Server Error 吗?不会。您会得到一个网页,该网页带有 200 OK 状态代码,其文本在某处显示“哎呀,您的密码错误”。

以上都说了,我现在来回答你的问题。

a) 告诉 PHP 发送 500 之类的标头 如果发生错误?或 b) 使用 set_error_handler 发送一个 500-header 然后调用 PHP 常规 错误处理?或者 c) 你能在任何 其他方式在 PHP 时发送错误标头 出现错误?

在上述所有情况下,只要您想发送状态标头,您都可以使用库 header 函数来完成。

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

您可以在错误处理程序中或任何您喜欢的地方编写它。

您无法控制发生 PHP 解析错误时发生的情况。您的应用程序将不得不假设您已经测试了所有 PHP 脚本并且它们可以解析;这似乎并不难保证。

【讨论】:

  • 感谢关于 5xx 错误的部分。我想我只会发送一个完全自定义的标题消息。我仍然想知道是否有一种方便的方法可以在发生 PHP 错误时自动发送标头,除了负责整个错误处理。
  • @Lukas:是的,正如我所说,使用错误处理程序。并且注意不要发送非标准的 HTTP 标头;坚持 HTTP 标头的正确含义。
  • 嗯,是否有任何适用于应用程序中错误的标题?在这种情况下,rails 不会发送 500 吗?
  • @Lukas:不,没有这样合适的标题。 HTTP 错误描述了应用程序执行 失败,而不是在应用程序执行 发生的错误。如果 Rails 照你说的做,我不同意他们的决定。
  • 不幸的是,我不能接受 2 个正确答案,stereofrog 的回复回答了原始问题。但是谢谢,我现在只是返回指示错误而不是标题的 json!
【解决方案3】:

使用header() 函数。

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

http://uk.php.net/manual/en/function.header.php

【讨论】:

  • 问题不在于发送标头。问题是如何在发生错误时发送标头,同时最好保持 PHP 的常规错误处理能力。
【解决方案4】:

您可以使用 PHP 的 header() 函数来设置返回不同的标头。

确实,对于不可恢复的服务器错误,您应该只使用 5xx 错误 - 所以在 set_error_handler 中,您可以检查错误的级别并在需要时返回 500。

对于您可以处理的错误,您可以考虑可用的4xx 状态码范围,或者在返回的 JSON 中包含一组错误信息

【讨论】:

  • s/on the server side/on the client side/?
  • 当我说你可以在服务器端处理错误时,我说的是他的应用程序中听起来像是有错误的事实——你在指出这一点上做得很好。但是,是的,我想客户端也可以这样说。我只是将其更改为更具包容性:)
【解决方案5】:

使用set_error_handler()set_exception_handler(),您可以在发生错误时运行自己的代码。

这不会捕获 PHP 启动错误,并且在您设置错误处理程序之前解析的任何 PHP 代码中都不会出现解析错误,但所有其他错误都应该是可捕获的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-03-25
    • 2020-04-10
    • 2022-11-18
    • 2022-12-05
    • 2015-09-14
    • 1970-01-01
    • 2014-10-03
    • 1970-01-01
    相关资源
    最近更新 更多