在REST API中,200响应显示成功操作。 PHP默认情况下直接在响应正文中输出错误消息而不更改响应代码。在SPA中,响应文本不会直接对用户可见。因此,当应用程序无法按预期工作时,我通过FireBug检查响应主体,以检查可能的PHP异常(导致无效的json响应)。 有没有办法在所有PHP错误上发送特定的HTTP代码?
有没有办法根据任何PHP错误的存在更改HTTP响应代码?或者,是否可以抓取错误文本并以无忧无虑的方式以json格式发送。 (在开发阶段)
更新:异常捕获(try / catch / final)不是我想要的。
答案 0 :(得分:10)
答案 1 :(得分:10)
例如,假设您只关注致命的运行时错误,致命的编译时错误和运行时警告。使用error_reporting()函数将错误报告设置为所需级别。
error_reporting( E_ERROR | E_COMPILE_ERROR | E_WARNING );
由于用户定义的错误处理程序(下面稍后)无法处理致命错误,因此仍会显示致命错误消息。为避免使用ini_set()函数并将display_errors
设置为零。
ini_set( 'display_errors', 0 );
现在使用set_error_handler()创建一个自定义错误处理程序,以完全绕过指定错误类型的PHP错误处理程序(不适用于致命错误)。
/* The following error types cannot be handled with a user defined function:
* E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING
* The standard PHP error handler is completely bypassed for the error types specified
* unless the callback function returns FALSE.
*/
function exception_error_handler( $severity, $message, $file, $line )
{
if ( !( error_reporting() & $severity ) ) {
// This error code is not included in error_reporting
return;
}
// code for handling errors
}
set_error_handler( "exception_error_handler" );
使用register_shutdown_function()关闭时可以处理致命错误。关闭处理程序在脚本完成后执行,或者终止(这也适用于错误)。我们需要获取有关上次发生的错误的信息(error_get_last()),然后检查这是否是我们跟踪的错误类型(由于{ {1}}不会被触发,但过滤错误会很有用),最后调用异常处理程序。
error_reporting
现在,您可以使用自定义异常处理程序来捕获未处理的异常(包括致命异常)并强制使用响应代码(使用header()函数)。
答案 2 :(得分:6)
set_error_handler
功能是我错过的。我想出了以下代码。欢迎任何更好的答案。
function jsonErrorHandler()
{
if (error_reporting()) {
http_response_code(500);
header('Content-Type: application/json; charset=utf-8');
$response = array_combine(['errno', 'errstr', 'errfile', 'errline', 'errcontext'], func_get_args());
die(json_encode($response));
}
}
set_error_handler('jsonErrorHandler');
答案 3 :(得分:5)
使用框架或an error handler library。
根据您选择的框架,您可以自定义错误处理程序如何显示错误。我链接的错误处理程序显然支持默认情况下将错误序列化为JSON,您应该查看其文档。
使用框架,这里是Laravel 4的example:
App::error(function(Exception $exception, $code) {
Log::error($exception);
return Response::json(["code" => $code, "message" => $exception->getMessage()], $code);
});
请注意,如果您依赖全局错误处理程序,那么其他地方通常会出现问题 - 您不应该依赖它来处理错误;而是在适当的地方使用try / catch。
答案 4 :(得分:3)
虽然您的问题的某些部分已在此处回答Returning http status codes with a rest api
我建议不要为许多警告,错误和通知发送不同的http代码。应该执行500(http代码500)内部服务器错误,您不需要向API使用者公开错误的细节。当然,您可以记录所有错误/通知/警告,以便调试和修复您的应用程序。
此外,它还取决于您的应用程序逻辑,以及需要向用户报告哪些错误,如数据验证,业务逻辑等。
答案 5 :(得分:3)
您可以使用register_shutdown_function()
和error_get_last()
PHP函数来捕获任何错误并返回有效响应。在There is a working example
答案 6 :(得分:3)
HTTP状态代码在HTTP响应的标头中发送,这意味着只要PHP没有向客户端发送任何字节,您就可以随时更改它。如果已经存在,则很可能会出现Cannot modify header information - headers already sent错误。
PHP有几个函数来更改状态代码,我建议使用http_response_code()
,因为它更容易使用:您只需要发送HTTP状态代码,它就会为您编写完整的标题。
要发现错误,我建议您设置error handler。
function log_error($errno, $errstr, $errfile = '', $errline = 0, $errcontext = array())
{
// Save the error to the error log.
// You may want to add more information than $errstr in the log, so feel free to change this line.
error_log($errstr);
// If headers haven't been sent, you can set a new one.
if (!headers_sent())
{
// 500 is the most generic error when the error comes from your application.
http_response_code(500);
// Checking if you're in debug mode allows you to show you errors while developping, and hiding them for users.
// Change this line by your own checks.
if (IS_DEBUG)
{
// Send the correct Content-Type header.
header('Content-Type: application/json; charset=utf-8');
// Sending information about the error.
echo json_encode(array(
'error' => $errstr // Once again, you may want to add more information.
));
// Exiting since we do not want the script to continue.
exit;
}
else
{
// Do whatever you want here, it will be shown to your users if you're not in debug mode.
// But do not forget to exit.
exit;
}
}
}
// Setting your function as an error handler.
set_error_handler('error_handler');
由于PHP中的错误处理程序不处理异常,我还建议设置exception handler。
您的应用程序在运行时遇到的每个PHP错误(例如,这不包括解析错误)现在将发送500 Internal Server Error
响应,如果您愿意,还会提供有关错误的详细信息。
答案 7 :(得分:1)
在Yii Framework中,非常有效地处理这些问题。
他们使用PHP的set_exception_handler('exceptionHandlerFunction')和set_error_handler('errorHandlerFunction')函数分别处理所有类型的异常和错误(警告,通知)。
关于致命错误,register_shutdown_function('fatalHandlerFunction')
现在,为了显示目的,Yii的效率非常高。
在错误/异常/致命处理程序函数中,它可以向客户端抛出错误或显示格式错误。
如果要显示格式良好的话,Yii正在将路由转移到SystemController的错误操作。
您也可以使用How Yii Handling Errors。
希望它有所帮助!!