Php 如何使Laravel为JSON REST API返回自定义错误
我正在开发某种RESTful API。当发生错误时,我抛出一个Php 如何使Laravel为JSON REST API返回自定义错误,php,json,rest,laravel-4,restful-architecture,Php,Json,Rest,Laravel 4,Restful Architecture,我正在开发某种RESTful API。当发生错误时,我抛出一个App::abort($code$message)错误 问题是:我希望他抛出一个json格式的数组,其中包含键“code”和“message”,每个键都包含上述数据 Array ( [code] => 401 [message] => "Invalid User" ) 有人知道这是否可能,如果可能,我是如何做到的吗?您可以向返回的JSON响应传递一个数组: $returnData = array(
App::abort($code$message)
错误
问题是:我希望他抛出一个json格式的数组,其中包含键“code”和“message”,每个键都包含上述数据
Array
(
[code] => 401
[message] => "Invalid User"
)
有人知道这是否可能,如果可能,我是如何做到的吗?您可以向返回的JSON响应传递一个数组:
$returnData = array(
'status' => 'error',
'message' => 'An error occurred!'
);
return Response::json($returnData, 500);
转到你的
应用程序/start/global.php
这将把401
和404
的所有错误转换为自定义json错误,而不是Whoops stacktrace。添加以下内容:
App::error(function(Exception $exception, $code)
{
Log::error($exception);
$message = $exception->getMessage();
// switch statements provided in case you need to add
// additional logic for specific error code.
switch ($code) {
case 401:
return Response::json(array(
'code' => 401,
'message' => $message
), 401);
case 404:
$message = (!$message ? $message = 'the requested resource was not found' : $message);
return Response::json(array(
'code' => 404,
'message' => $message
), 404);
}
});
这是处理此错误的许多选项之一
制作API最好是创建自己的助手,比如扩展
Response
类的Responser::error(400,'damn')
有点像:
public static function error($code = 400, $message = null)
{
// check if $message is object and transforms it into an array
if (is_object($message)) { $message = $message->toArray(); }
switch ($code) {
default:
$code_message = 'error_occured';
break;
}
$data = array(
'code' => $code,
'message' => $code_message,
'data' => $message
);
// return an error
return Response::json($data, $code);
}
以下是我使用的(Laravel 5.2):
根据:,我们可以为app\Exceptions\Handler.php
中的错误指定自定义呈现函数。我所做的只是将渲染函数更改为:
/**
* Render an exception into an HTTP response.
* Updated to return json for a request that wantsJson
* i.e: specifies
* Accept: application/json
* in its header
*
* @param \Illuminate\Http\Request $request
* @param \Exception $e
* @return \Illuminate\Http\Response
*/
public function render($request, Exception $e)
{
if ($request->ajax() || $request->wantsJson()) {
return response()->json(
$this->getJsonMessage($e),
$this->getExceptionHTTPStatusCode($e)
);
}
return parent::render($request, $e);
}
protected function getJsonMessage($e){
// You may add in the code, but it's duplication
return [
'status' => 'false',
'message' => $e->getMessage()
];
}
protected function getExceptionHTTPStatusCode($e){
// Not all Exceptions have a http status code
// We will give Error 500 if none found
return method_exists($e, 'getStatusCode') ?
$e->getStatusCode() : 500;
}
/**
* Render an exception into an HTTP response.
*
* @param \Illuminate\Http\Request $request
* @param \Exception $e
*
* @return Response
*/
public function render($request, Exception $e)
{
if ($request->wantsJson() && !($e instanceof ValidationException)) {
$response = [
'message' => (string)$e->getMessage(),
'status_code' => 400,
];
if ($e instanceof HttpException) {
$response['message'] = Response::$statusTexts[$e->getStatusCode()];
$response['status_code'] = $e->getStatusCode();
} else if ($e instanceof ModelNotFoundException) {
$response['message'] = Response::$statusTexts[Response::HTTP_NOT_FOUND];
$response['status_code'] = Response::HTTP_NOT_FOUND;
}
if ($this->isDebugMode()) {
$response['debug'] = [
'exception' => get_class($e),
'trace' => $e->getTrace()
];
}
return response()->json([
'status' => 'failed',
'status_code' => $response['status_code'],
'massage' => $response['message'],
], $response['status_code']);
}
return parent::render($request, $e);
}
在此之后,您需要做的就是确保所有API请求都指定
Accept:application/json
头。希望这有帮助:)根据Ibrahim的回答,并不是每个ajax请求都需要JSON,响应“状态代码”和“状态”是不必要的,因为它们都表示相同的意思。更重要的是,根本不需要在响应中提到“状态”,因为响应代码“说明”了这一点。类似的东西应该可以完美地工作:
/**
* Render an exception into an HTTP response.
*
* @param \Illuminate\Http\Request $request
* @param \Exception $e
* @return \Illuminate\Http\Response
*/
public function render($request, Exception $e)
{
if ($request->wantsJson())
return response()->json(
['message' => $e->getMessage()],
method_exists($e, 'getStatusCode') ? $e->getStatusCode() : 500);
return parent::render($request, $e);
}
以下是我在5.6中使用的方法,以返回与内置
validate
方法相同的响应类型:
response()代码>在Laravel5.6中,我通常在app\Exceptions\Handler.php
中为错误指定自定义渲染函数。我所做的只是将渲染函数更改为:
/**
* Render an exception into an HTTP response.
* Updated to return json for a request that wantsJson
* i.e: specifies
* Accept: application/json
* in its header
*
* @param \Illuminate\Http\Request $request
* @param \Exception $e
* @return \Illuminate\Http\Response
*/
public function render($request, Exception $e)
{
if ($request->ajax() || $request->wantsJson()) {
return response()->json(
$this->getJsonMessage($e),
$this->getExceptionHTTPStatusCode($e)
);
}
return parent::render($request, $e);
}
protected function getJsonMessage($e){
// You may add in the code, but it's duplication
return [
'status' => 'false',
'message' => $e->getMessage()
];
}
protected function getExceptionHTTPStatusCode($e){
// Not all Exceptions have a http status code
// We will give Error 500 if none found
return method_exists($e, 'getStatusCode') ?
$e->getStatusCode() : 500;
}
/**
* Render an exception into an HTTP response.
*
* @param \Illuminate\Http\Request $request
* @param \Exception $e
*
* @return Response
*/
public function render($request, Exception $e)
{
if ($request->wantsJson() && !($e instanceof ValidationException)) {
$response = [
'message' => (string)$e->getMessage(),
'status_code' => 400,
];
if ($e instanceof HttpException) {
$response['message'] = Response::$statusTexts[$e->getStatusCode()];
$response['status_code'] = $e->getStatusCode();
} else if ($e instanceof ModelNotFoundException) {
$response['message'] = Response::$statusTexts[Response::HTTP_NOT_FOUND];
$response['status_code'] = Response::HTTP_NOT_FOUND;
}
if ($this->isDebugMode()) {
$response['debug'] = [
'exception' => get_class($e),
'trace' => $e->getTrace()
];
}
return response()->json([
'status' => 'failed',
'status_code' => $response['status_code'],
'massage' => $response['message'],
], $response['status_code']);
}
return parent::render($request, $e);
}
拉维6:
您只需在客户端的API请求中设置Accept:application/json
头,Laravel将自动返回json格式错误
例如:
{
}
我真的很喜欢你说的第二件事。关于API,尽管我并不完全理解。我是否应该创建另一个类,在其中扩展Response
类并调用它,而不是“正确”的类?是这样吗?@DennisBraga没错。它可以帮助您在API中保持统一的错误响应。@PHPst对不起,我很久没有使用PHP/laravel了。谢谢!在laravel 5中,如果您减少$returnData数组的使用,那么:return response()->json($returnData,500)也会变得更容易。答案看起来非常好,但遗憾的是,它对我不起作用,laravel仍然会给我“status”error消息“发生错误”。“```作为响应:(你是国王!我只需要一小段代码就可以处理ajax响应。很酷。示例:abort(401,“未授权”);