How to modify request input after validation in laravel?

ava*_*sin 9 php laravel

我找到了Request::replace方法,它允许替换 Request 中的输入参数。

但目前我只能看到一种实现它的方法 - 在每个控制器操作中编写相同的替换输入代码。

是否可以以某种方式对代码进行分组,这些代码将在请求成功验证之后、但在控制器操作开始之前执行?

例如,我需要在我的 api 中支持 ISO2 语言,但在幕后,我必须将它们转换为遗留语言,这些语言实际上存储在数据库中。目前我在控制器中有这段代码:

// Controller action context
$iso = $request->input('language');
$legacy = Language::iso2ToLegacy($iso);
$request->replace(['language' => $legacy]);

// Controller action code starts
Run Code Online (Sandbox Code Playgroud)

Ale*_*nko 11

我认为你正在寻找的是passedValidation()来自ValidatesWhenResolvedTrait特质的方法

如何使用它:

  1. 创建自定义请求:php artisan make:request UpdateLanguageRequest
  2. 将验证规则放入类rules()内的方法中UpdateLanguageRequest
  3. 验证成功后使用passedValidation()方法对 Request 对象进行任何操作
namespace App\Http\Requests;

use App\...\Language;

class UpdateLanguageRequest extends FormRequest
{
    public function authorize()
    {
        return true;
    }


    public function rules()
    {
        return [
            // here goes your rules, f.e.:
            'language' => ['max:255']
        ];
    }


    protected function passedValidation()
    {
        $this->replace(['language' => Language::iso2ToLegacy($this->language)]);
    }
}

Run Code Online (Sandbox Code Playgroud)
  1. UpdateLanguageRequest在你的控制器中使用类Request
public function someControllerMethod(UpdateLanguageRequest $request){
    // the $request->language data was already modified at this point
}

Run Code Online (Sandbox Code Playgroud)

*也许您不想使用merge方法replace,因为替换将替换请求中的所有其他数据,而该merge方法将仅替换特定值


The*_*pha 0

是否可以以某种方式对代码进行分组,这些代码将在请求成功验证之后、但在控制器操作开始之前执行?

您可以使用中间件作为验证器来完成此操作,例如:

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\JsonResponse;

class InputValidator
{
    public function handle($request, Closure $next, $fullyQualifiedNameOfModel)
    {
        $model = app($fullyQualifiedNameOfModel);

        $validator = app('validator')->make($request->input(), $model->rules($request));

        if ($validator->fails()) {

            return $this->response($request, $validator->errors());
        }

        return $next($request);
    }

    protected function response($request, $errors)
    {
        if($request->ajax()) {
            return new JsonResponse($errors, 422);
        }

        return redirect()->back()->withErrors($errors)->withInput();
    }
}
Run Code Online (Sandbox Code Playgroud)

$routeMiddleware在类末尾添加以下条目App\Http\Kernel.php

'validator' => 'App\Http\Middleware\InputValidator'
Run Code Online (Sandbox Code Playgroud)

例如,在is modelrules中添加方法,并且该方法声明如下:Eloquent Modelapp\Product.phprules

/**
 * Get the validation rules that apply to the request.
 *
 * @return array
 */
public function rules(\Illuminate\Http\Request $request)
{
    return [
        'title' => 'required|unique:products,title,'.$request->route()->parameter('id'),
        'slug' => 'required|unique:products,slug,'.$request->route()->parameter('id'),
    ];
}
Run Code Online (Sandbox Code Playgroud)

像这样声明路线:

$router->get('create', [
    'uses' => 'ProductController@create',
    'as' => 'Product.create',
    'permission' => 'manage_tag',
    'middleware' => 'validator:App\Product' // Fully qualified model name
]);
Run Code Online (Sandbox Code Playgroud)

您可以middleware使用数组添加更多内容,例如:

'middleware' => ['auth', 'validator:App\Product']
Run Code Online (Sandbox Code Playgroud)

这是一种使用FormRequest单个middleware. 我使用它middleware作为model name参数来验证我的所有模型,为每个控制器使用单个类middleware而不是单独的FormRequest类。

这里,validatormiddlewareApp\Product是我作为参数传递的模型名称,并从内部middleware验证该模型。

根据您的问题,控制器内的代码仅在输入验证通过后才会执行,否则将redirect/ajax response完成。由于您的具体原因,您可以创建一个特定的middleware. 这只是一个可以在您的案例中使用的想法,IMO,我的意思是您可以在middleware验证通过后添加用于替换特定输入的代码。