我怎么能遇到一个致命的exceptionPHP返回500?
PHP致命错误作为状态码200回到HTTP客户端。 我怎样才能让它返回一个状态代码500(内部服务器错误)?
header("HTTP/1.1 500 Internal Server Error");
这正是我昨天遇到的问题,我发现解决scheme如下:
1)首先,你需要捕获PHP致命错误,这是错误typesE_ERROR。 当发生这个错误时,脚本将被存储错误并终止执行。 你可以通过调用函数error_get_last()来获得存储的错误。
2)在脚本终止之前,一个callback函数register_shutdown_function()将会被调用。 所以你需要通过这个函数来注册一个error handling程序来做你想做的事情,在这种情况下,返回头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 *开头的自定义错误types,则可以使用函数set_error_handler()来注册error handling程序,并通过函数trigger_error触发错误,但是,此error handling程序无法处理E_ERROR错误types。 请参阅php.net关于error handling程序的解释
我用“set_exception_handler”来处理未捕获的exception。
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');
根据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()引发。
当然,你可以捕捉任何exception(即使是本地PHP函数抛出的exception)。
我同意这是一个问题。 当应用程序代码崩溃和灼伤时,服务器不应该返回200 OK。
你可以使用phperror handling
你将不得不赶上使用try / catch抛出的错误,然后使用该catch块发送一个500错误的头() 。
try { ...badcode... throw new Exception('error'); } catch (Exception $e) { header("Status: 500 Server Error"); var_dump($e->getMessage()); }
如果致命exception没有被try {} catch块所包围,那么你必须注册一个全局处理器,并在脚本结束时使用register_shutdown_function()
来检查错误。
永远不要忘记设置header("HTTP/1.1 200 OK", true, 200);
作为任何执行path的最后一行:
//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
你可以使用更好的http_response_code(200)
或http_response_code(500)
replace上面的header
函数。
在处理致命错误(编译错误,例如缺less分号)时,遇到的困难是脚本将不会被执行,因此无法在该脚本中设置状态码。 但是,当您包含或需要脚本时,无论包含脚本中的错误如何,都将执行调用脚本。 有了这个,我来解决这个问题:
坚如磐石的-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");
脚本我想做某些后卫换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标志,但是这完全阻止了PHP的执行,所以这是没有用的。
发生错误时,标准PHPconfiguration确实会返回500! 只要确保你的display_errors = off。 你可以用下面的方法来模拟它:
ini_set('display_errors', 0); noFunction();
在生产display_errors指令是默认closures。