我找到了方法Request::replace,它允许替换Request中的输入参数。
但是目前我只能看到一种方法来实现它 - 在每个控制器动作中编写相同的替换输入代码。
是否有可能以某种方式对代码进行分组,这将在请求成功验证后执行,但在控制器操作开始之前执行?
例如,我需要在我的api中支持ISO2语言,但在引擎盖下,我必须将它们转换为遗留的,真正存储在数据库中。目前我在控制器中有这个代码:
// Controller action context
$iso = $request->input('language');
$legacy = Language::iso2ToLegacy($iso);
$request->replace(['language' => $legacy]);
// Controller action code starts
答案 0 :(得分:1)
我认为您正在寻找的是 passedValidation()
trait 中的 ValidatesWhenResolvedTrait
方法
使用方法:
php artisan make:request UpdateLanguageRequest
rules()
类中的 UpdateLanguageRequest
方法passedValidation()
方法在验证成功后对请求对象进行任何操作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)]);
}
}
UpdateLanguageRequest
类代替 Request
public function someControllerMethod(UpdateLanguageRequest $request){
// the $request->language data was already modified at this point
}
*也许您想使用 merge
而不是 replace
方法,因为 replace 将替换请求中的所有其他数据,而 merge
方法将仅替换特定值
答案 1 :(得分: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();
}
}
在$routeMiddleware
课程中的App\Http\Kernel.php
末尾添加以下条目:
'validator' => 'App\Http\Middleware\InputValidator'
在rules
中添加Eloquent Model
方法,例如app\Product.php
是模型,rules
方法声明如下:
/**
* 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'),
];
}
声明这样的路线:
$router->get('create', [
'uses' => 'ProductController@create',
'as' => 'Product.create',
'permission' => 'manage_tag',
'middleware' => 'validator:App\Product' // Fully qualified model name
]);
您可以使用数组添加更多middleware
,例如:
'middleware' => ['auth', 'validator:App\Product']
这是一种使用单个FormRequest
替换middleware
的方法。我使用此middleware
和model name
作为参数,使用单个middleware
代替每个控制器的单个FormRequest
类来验证我的所有模型。
此处,validator
是middleware
,App\Product
是我作为参数传递的模型名称,并且来自middleware
我验证该模型。
根据您的问题,控制器内的代码只有在输入验证通过后才会执行,否则redirect/ajax response
将完成。出于特定原因,您可以创建特定的middleware
。这只是一个可以在您的IMO案例中使用的想法,我的意思是您可以在验证通过后添加用于替换特定middleware
中的输入的代码。
答案 2 :(得分:0)
根据上面的 Alexander Ivashchenko 回答,此解决方案对我有用:
<?php
namespace App\Http\Requests\User;
class UserUpdateRequest extends UserRequest
{
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules(): array
{
return [
'name'=>'required|string',
'email'=>'required|string|email',
'password'=>'min:8'
];
}
}
我们的父 UserRequest
类:
<?php
namespace App\Http\Requests\User;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Hash;
abstract class UserRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize(): bool
{
return true;
}
/**
* Handle a passed validation attempt.
*
* @return void
*/
protected function passedValidation()
{
if ($this->has('password')) {
$this->merge(
['password' => Hash::make($this->input('password'))]
);
}
}
public function validated(): array
{
if ($this->has('password')) {
return array_merge(parent::validated(), ['password' => $this->input('password')]);
}
return parent::validated();
}
}
我也在覆盖经过验证的方法。如果我们单独访问每个输入元素,他的答案有效,但为了在我们的控制器中使用批量分配,我们需要 validated
覆盖。
...
public function update(UserUpdateRequest $request, User $user): JsonResource
{
$user->update($request->validated());
...
}
...
发生这种情况是因为 validated
方法直接从验证器而不是请求中获取数据。另一种可能的解决方案可能是使用 DTO 方法的自定义验证器,但对于上面的简单内容就足够了。