Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/239.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何使Laravel为JSON REST API返回自定义错误_Php_Json_Rest_Laravel 4_Restful Architecture - Fatal编程技术网

Php 如何使Laravel为JSON REST 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(

我正在开发某种RESTful API。当发生错误时,我抛出一个
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,“未授权”);