laravel 中自动批量注册验证规则到验证器
创建抽象验证规则 App\Rules\Rule
、App\Rules\RegexRule
<?php
namespace App\Rules;
use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Support\Str;
abstract class Rule implements ValidationRule
{
abstract public function passes(string $attribute, mixed $value): bool;
public function validate(string $attribute, mixed $value, \Closure $fail): void
{
if (! $this->passes($attribute, $value)) {
$fail(static::message())->translate();
}
}
/**
* 规则名称
*/
public static function name(): string
{
return Str::of(class_basename(static::class))->replaceLast('Rule', '')->snake();
}
/**
* 错误消息
*/
public static function message(): string
{
$transMessage = __($transKey = sprintf('validation.%s', static::name()));
return $transMessage === $transKey ? static::fallbackMessage() : $transMessage;
}
/**
* 扩展方法
*/
public static function extendMethod(): string
{
$ruleReflectionClass = new \ReflectionClass(static::class);
$isImplicit = $ruleReflectionClass->getDefaultProperties()['implicit'] ?? false;
if ($isImplicit) {
return 'extendImplicit';
}
// extendDependent todo
return 'extend';
}
/**
* 回退错误消息
*/
protected static function fallbackMessage(): string
{
return __(
app()->isLocale('zh_CN')
? ':Attribute [:input] 必须是有效的 :Name。'
: 'The :attribute [:input] must be a valid :Name.',
[
'name' => value(static function () {
$name = __($key = sprintf('validation.attributes.%s', static::name()));
return $name === $key ? str(static::name())->replace('_', ' ') : $name;
}),
]
);
}
}
<?php
namespace App\Rules;
abstract class RegexRule extends Rule
{
abstract protected function pattern(): string;
public function passes(string $attribute, mixed $value): bool
{
return (bool) preg_match($this->pattern(), $value);
}
}
创建验证规则特性 App\Rules\Concerns\DataAware
、App\Rules\Concerns\ValidatorAware
<?php
namespace App\Rules\Concerns;
trait DataAware
{
protected array $data;
public function setData(array $data): self
{
$this->data = $data;
return $this;
}
}
<?php
namespace App\Rules\Concerns;
use Illuminate\Validation\Validator;
trait ValidatorAware
{
protected Validator $validator;
public function setValidator(Validator $validator): self
{
$this->validator = $validator;
return $this;
}
}
创建验证规则
普通验证规则
<?php
namespace App\Rules;
final class Base64Rule extends Rule
{
public function passes(string $attribute, mixed $value): bool
{
return base64_encode(base64_decode($value, true)) === $value;
}
}
正则验证规则
<?php
namespace App\Rules;
final class PhoneRule extends RegexRule
{
protected function pattern(): string
{
/** @lang PhpRegExp */
return '/^(?:(?:\+|00)86)?1[3-9]\d{9}$/';
}
}
隐式验证规则
<?php
namespace App\Rules;
use App\Rules\Concerns\DataAware;
use App\Rules\Concerns\ValidatorAware;
use Illuminate\Contracts\Validation\ValidatorAwareRule;
final class DefaultRule extends Rule implements ValidatorAwareRule
{
// use DataAware;
use ValidatorAware;
public bool $implicit = true;
public function __construct(protected mixed $default) {}
public function passes(string $attribute, mixed $value): bool
{
if ($value === null) {
$data = $this->validator->getData();
$data[$attribute] = $this->default;
$this->validator->setData($data);
}
return true;
}
}
注册验证规则到验证器
注册验证规则
<?php
namespace App\Providers;
use App\Rules\Rule;
use App\Support\Discover;
use Illuminate\Contracts\Validation\DataAwareRule;
use Illuminate\Contracts\Validation\ValidatorAwareRule;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
public function register(): void {}
public function boot(): void
{
Discover::in('Rules')
->instanceOf(Rule::class)
->all()
->each(static function (\ReflectionClass $ruleReflectionClass, $ruleClass): void {
/** @var Rule&class-string $ruleClass */
Validator::{$ruleClass::extendMethod()}(
$ruleClass::name(),
static fn (
string $attribute,
mixed $value,
array $parameters,
\Illuminate\Validation\Validator $validator
): bool => tap(new $ruleClass(...$parameters), static function (Rule $rule) use ($validator): void {
$rule instanceof ValidatorAwareRule and $rule->setValidator($validator);
$rule instanceof DataAwareRule and $rule->setData($validator->getData());
})->passes($attribute, $value),
$ruleClass::message()
);
});
}
}
验证
<?php
use App\Rules\Base64Rule;
use App\Rules\PhoneRule;
use Illuminate\Support\Facades\Validator;
$validator = Validator::make(
[
'base64' => 'foo',
'phone' => 'bar',
],
[
// 'base64' => new Base64Rule(),
'base64' => 'base64', // 验证规则名称
'phone' => new PhoneRule(), // 验证规则实例
// 'phone' => 'phone',
]
);
dump($validator->errors()->all());
$validator = Validator::make(
[
// 'default' => 'baz',
],
[
'default' => 'default:baz',
]
);
dump($validator->validate());
array:2 [
0 => "Base64 [foo] 必须是有效的 Base64。"
1 => "电话 [bar] 必须是有效的 电话。"
]
array:1 [
"default" => "baz"
]
相关连接
原文连接
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。