如何在 Laravel 5.5 的 FormRequest 类中返回自定义响应?

Posted

技术标签:

【中文标题】如何在 Laravel 5.5 的 FormRequest 类中返回自定义响应?【英文标题】:How i can return a customized response in a FormRequest class in Laravel 5.5? 【发布时间】:2018-03-01 17:09:58 【问题描述】:

我正在制作一个 API,我想返回错误数组,其格式与我通过手动方式验证请求时$validator->errors(); 生成的格式相同。但我无法操纵响应。我想找到正确的方法。

这可以在 Laravel 5.4 中使用 formatErrors 方法并在 FormRequest 类中包含 Illuminate\Contracts\Validation\Validator 类来完成,但对于 5.5 版它不起作用。我不知道该怎么做。

这是我的控制器:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Http\Requests\ProductRequest;
use Illuminate\Validation\Rule;
use App\Product;

class ProductController extends Controller

    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index(ProductRequest $request)
    
        $products = Product::where('code', 'LIKE', '%'.$request->input('search').'%')
        ->where('name', 'LIKE', '%'.$request->input('search').'%')
        ->paginate(10);
        $products->withPath($request->fullUrl());
        return $products;
    

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    

    

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(ProductRequest $request)
    
        $product = new Product($request->validated());
        $product->save();
        return response('', 201);
    

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    
        $product = Product::find($id);
        return response($product, 200);
    

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    
        //
    

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(ProductRequest $request, $id)
    
        $product = Product::find($id);
        $product->fill($request->validated());
        $product->save();
        return response('', 200);
    

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    
        $product = Product::find($id);
        $product->delete();
        return response('', 204);
    

这是我的 FormRequest 类

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;

class ProductRequest extends FormRequest

    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    
        return true;
    

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    
        switch($this->method())
        
            case 'GET':
            
                return [
                    'code' => 'string',
                    'name' => 'string',
                ];
             break;
            case 'POST':
            
                return [
                    'code' => 'required|unique:Products,code',
                    'name' => 'required',
                    'description' => 'required',
                    'quantity' => 'required|min:0',
                    'price' => 'required|numeric',
                    'extemp' => [
                        Rule::in(['tax', 'free']),
                    ]
                ];
             break;
            case 'PUT':
            
                return [
                    'code' => 'unique:products,code,'.$this->route('product'),
                    'name' => 'string:min:1',
                    'description' => 'string|min:1',
                    'quantity' => 'integer|min:0',
                    'price' => 'numeric',
                    'extemp' => [
                        Rule::in(['tax', 'free']),
                    ],
                ];
             break;
            case 'PATCH': break;
            case 'DELETE': break;
            default:
            
                return [];
             break;
        
    

    /**
     * Get the error messages for the defined validation rules.
     *
     * @return array
     */
    public function messages()
    
        return [
            //Product
            'code.required' => 'El :attribute es obligatorio.',
            'code.unique' => 'El :attribute ya se encuentra registrado.',
            'name.required' => 'El :attribute es obligatorio.',
            'name.min' => 'El :attribute es obligatorio.',
            'description.required' => 'El :attribute es obligatorio.',
            'description.min' => 'El :attribute es obligatorio.',
            'quantity.required' => 'La :attribute es obligatoria.',
            'quantity.integer' => 'La :attribute debe ser un número entero.',
            'quantity.min' => 'La :attribute debe ser al menos :min.',
            'price.required' => 'El :attribute es obligatorio.',
            'price.numeric' => 'El :attribute debe ser un valor numérico.',
            'extemp.in' => 'El :attribute seleccionado es inválido.',
        ];
    
    public function attributes()
        return [
            'code' => 'código',
            'name' => 'nombre',
            'description' => 'descripción',
            'quantity' => 'cantidad',
            'price' => 'precio',
            'extemp' => 'exento',
        ];
    

我的回应:


    "message": "The given data was invalid.",
    "errors": 
        "code": [
            "El código es obligatorio."
        ],
        "name": [
            "El nombre es obligatorio."
        ],
        "description": [
            "El descripción es obligatorio."
        ],
        "quantity": [
            "La cantidad es obligatoria."
        ],
        "price": [
            "El precio es obligatorio."
        ]
    

我想要的回应(与$validator-&gt;errors();

[
    "El código es obligatorio.",
    "El nombre es obligatorio.",
    "El descripción es obligatorio.",
    "La cantidad es obligatoria.",
    "El precio es obligatorio."
]

【问题讨论】:

试试这个$validator-&gt;errors()-&gt;all(); @Maraboc 是正确的,特别是如果它的自定义验证但对于表单请求,那么这可能不起作用 【参考方案1】:

您必须覆盖 failedValidation() 方法并发出带有您想要的响应的异常。 因此,您需要在 RequestForm 类中使用Illuminate\Contracts\Validation\ValidatorIlluminate\Http\Exceptions\HttpResponseException,并重写failedValidation() 方法:

protected function failedValidation(Validator $validator)  
        throw new HttpResponseException(response()->json($validator->errors()->all(), 422)); 

【讨论】:

谢谢!完美运行!【参考方案2】:

为此需要覆盖您的请求文件中的failedValidation() 函数。

protected function failedValidation(Validator $validator)

    throw new HttpResponseException(response()->json([
      'errors' => $validator->errors(),
      'status' => false
    ], 422));

为了使它工作use这些命名空间:

对于 laravel 5.4 及以上版本:

 use Illuminate\Contracts\Validation\Validator;

 use Illuminate\Http\Exceptions\HttpResponseException;

description here

低于 laravel 5.4:

use Illuminate\Contracts\Validation\Validator;
use Illuminate\Http\Exception\HttpResponseException;

description here

【讨论】:

【参考方案3】:

就我而言,我使用 Laravel 7 并稍作改动:

//add depences
use Illuminate\Http\Exceptions\HttpResponseException;
use Illuminate\Contracts\Validation\Validator;

//override this method in your FormRequest
protected function failedValidation(Validator $validator)
  throw new HttpResponseException(response()->json($validator->errors(), 422)); 

【讨论】:

以上是关于如何在 Laravel 5.5 的 FormRequest 类中返回自定义响应?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 laravel 5.5 中运行 phpunit

如何在 laravel 5.5 中获取验证消息

如何在 laravel 5.5 中使用 Noty 包

Laravel 5.5 中的多字段排序

如何在 laravel 5.5 中验证 Mailchimp api 密钥

如何将 laravel 日志文件数据存储到数据库中(5.5)[关闭]