illuminatech / validation-composite
允许将多个验证规则合并为一个,便于重用
Requires
- illuminate/support: ^6.0 || ^7.0 || ^8.0 || ^9.0 || ^10.0 || ^11.0
Requires (Dev)
- illuminate/validation: *
- phpunit/phpunit: ^7.5 || ^8.0 || ^9.3 || ^10.5
README
Laravel 复合验证
此扩展允许将多个 Laravel 验证规则合并为一个,便于重用。
有关许可信息,请查看LICENSE文件。
安装
安装此扩展的首选方式是通过composer。
运行以下命令:
php composer.phar require --prefer-dist illuminatech/validation-composite
或者将以下内容添加到你的 composer.json 文件中 require 部分:
"illuminatech/validation-composite": "*"
to the require section of your composer.json.
使用方法
验证规则的相同顺序可能在整个应用程序中多次重复。例如:您可能有一组与用户密码相关的限制,例如它应该至少有8个符号长,但不超过200个符号以适应为其存储预留的数据库字段。您的程序也可能允许用户上传一张图片作为其头像,但为了使其安全,您应该验证上传文件的 mime 类型和大尺寸。因此,用户个人资料表单的验证可能如下所示:
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; class ProfileController extends Controller { public function update(Request $request) { $validatedData = $request->validate([ 'password' => ['required', 'string', 'min:8', 'max:200'], 'avatar' => ['required', 'file', 'mimes:png,jpg,jpeg', 'max:1024'], // ... ]); // ... } }
问题是:用户密码或头像的验证可能出现在几个不同的地方。例如:密码可以在注册过程中设置,在密码重置期间等。您可能还有一个独立的管理面板,允许系统管理员调整现有用户记录或创建新的记录。因此,您将不得不在项目源代码的多个地方重复这些验证规则。如果要求更改,例如:我们决定密码长度至少应为10个符号而不是8个,或禁止 '*.png' 文件作为头像 - 您将不得不手动更改所有这些地方的验证规则。
此扩展允许将多个验证规则合并为一个,便于重用。对于上面的例子,您应该创建2个独立的验证规则类,它们扩展了Illuminatech\Validation\Composite\CompositeRule
<?php namespace App\Rules; use Illuminatech\Validation\Composite\CompositeRule; class PasswordRule extends CompositeRule { protected function rules(): array { return ['string', 'min:8', 'max:200']; } } class AvatarRule extends CompositeRule { protected function rules(): array { return ['file', 'mimes:png,jpg,jpeg', 'max:1024']; } }
在此方法rules()
中定义了要由定义的规则内部应用的一系列验证规则。现在我们可以用以下方式重写表单验证:
<?php namespace App\Http\Controllers; use App\Rules\AvatarRule; use App\Rules\PasswordRule; use Illuminate\Http\Request; class ProfileController extends Controller { public function update(Request $request) { $validatedData = $request->validate([ 'password' => ['required', new PasswordRule], 'avatar' => ['required', new AvatarRule], // ... ]); // ... } }
使用这种方法,您可以在单个地方更改 'password' 和 'avatar' 的验证。
如果复合验证规则失败,验证器实例将从特定的子规则中选取错误信息。例如:
<?php use App\Rules\PasswordRule; use Illuminate\Support\Facades\Validator; $validator = Validator::make( ['password' => 'short'], [ 'password' => ['required', new PasswordRule], ] ); if ($validator->fails()) { echo $validator->errors()->first('password'); // outputs 'The password must be at least 8 characters.' }
注意:不要在复合规则中使用像 'sometimes'、'required'、'required_with'、'required_without' 等规则。这些规则在不同的验证级别上处理,因此可能没有效果或可能表现出意外的行为。
您可以使用验证工厂扩展功能定义复合验证规则。对于这种情况,您可以使用Illuminatech\Validation\Composite\DynamicCompositeRule
。例如:
<?php namespace App\Providers; use Illuminate\Contracts\Validation\Factory; use Illuminate\Support\ServiceProvider; use Illuminatech\Validation\Composite\DynamicCompositeRule; class AppServiceProvider extends ServiceProvider { public function boot() { $this->app->extend('validator', function (Factory $validatorFactory) { $validatorFactory->extend('password', function ($attribute, $value) { return (new DynamicCompositeRule(['string', 'min:8', 'max:200']))->passes($attribute, $value); }); $validatorFactory->extend('avatar', function ($attribute, $value) { return (new DynamicCompositeRule(['file', 'mimes:png,jpg,jpeg', 'max:1024']))->passes($attribute, $value); }); return $validatorFactory; }); // ... } }
注意,使用这种方法,自动提取验证错误信息变得不可能,您将不得不在语言文件中显式设置它。
您可以为复合验证规则中使用的每个验证规则指定自定义错误信息,覆盖messages()
方法。例如:
<?php namespace App\Rules; use Illuminatech\Validation\Composite\CompositeRule; class PasswordRule extends CompositeRule { protected function rules(): array { return ['string', 'min:8', 'max:200']; } protected function messages(): array { return [ 'string' => 'Only string is allowed.', 'min' => ':attribute is too short.', 'max' => ':attribute is too long.', ]; } }