本文目录导读:

在PHP项目中,自定义验证规则是框架验证器非常重要的功能扩展点,不同框架的实现方式略有不同,下面以主流的 Laravel、ThinkPHP、Symfony 和 Hyperf 为例,介绍如何自定义验证规则。
Laravel 框架
使用 Artisan 命令生成规则类(推荐)
php artisan make:rule Uppercase
生成的类 app/Rules/Uppercase.php:
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
class Uppercase implements Rule
{
public function passes($attribute, $value)
{
return strtoupper($value) === $value;
}
public function message()
{
return ':attribute 必须全部大写。';
}
}
在控制器中使用:
use App\Rules\Uppercase;
$request->validate([
'name' => ['required', new Uppercase],
]);
使用闭包(简单场景)
$request->validate([ => [
'required',
function ($attribute, $value, $fail) {
if (strlen($value) > 100) {
$fail($attribute.' 不能超过100字符。');
}
},
],
]);
扩展 Validator 类(全局生效)
在 AppServiceProvider 的 boot 方法中:
use Illuminate\Support\Facades\Validator;
Validator::extend('phone', function ($attribute, $value, $parameters, $validator) {
return preg_match('/^1[3-9]\d{9}$/', $value);
});
// 同时注册错误消息
Validator::replacer('phone', function ($message, $attribute, $rule, $parameters) {
return str_replace(':attribute', $attribute, '请输入有效的手机号');
});
ThinkPHP 6.0/8.0 框架
使用验证器类的自定义规则方法
namespace app\validate;
use think\Validate;
class UserValidate extends Validate
{
protected $rule = [
'phone' => 'require|phone',
];
protected $message = [
'phone.phone' => '手机号格式不正确',
];
// 自定义验证规则方法(方法名格式:checkXxx)
protected function checkPhone($value, $rule, $data = [], $field = '')
{
return (bool) preg_match('/^1[3-9]\d{9}$/', $value);
}
}
使用扩展规则(全局)
在 app/provider.php 或 service.php 中注册:
use think\Validate;
Validate::maker(function ($validate) {
$validate->extend('phone', function ($value, $rule, $data, $field, $title) {
return preg_match('/^1[3-9]\d{9}$/', $value) ? true : '手机号格式错误';
});
});
闭包规则(ThinkPHP 6+)
$validate = new \think\Validate();
$validate->rule([
'username' => function ($value) {
if (strlen($value) < 6) {
return '用户名长度至少6位';
}
return true;
}
]);
Symfony 框架(使用约束组件)
创建自定义约束类
// src/Validator/Constraints/ContainsAlphanumeric.php
namespace App\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
class ContainsAlphanumeric extends Constraint
{
public $message = '字符串 "{{ value }}" 只能包含字母或数字。';
}
创建验证器类
// src/Validator/Constraints/ContainsAlphanumericValidator.php
namespace App\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
class ContainsAlphanumericValidator extends ConstraintValidator
{
public function validate($value, Constraint $constraint)
{
if (!preg_match('/^[a-zA-Z0-9]+$/', $value, $matches)) {
$this->context->buildViolation($constraint->message)
->setParameter('{{ value }}', $value)
->addViolation();
}
}
}
使用自定义约束
use App\Validator\Constraints\ContainsAlphanumeric;
class User
{
#[ContainsAlphanumeric]
private $username;
}
Hyperf 框架
注解方式自定义
use Hyperf\Validation\Annotation\Validation;
class DemoController extends AbstractController
{
#[Validation(messages: [
'phone.phone' => '手机号格式错误',
])]
public function store()
{
$validator = $this->validationFactory->make($this->request->all(), [
'phone' => 'required|phone',
]);
// 自定义验证规则需要在启动时注册
}
}
通过 ValidatorFactory 扩展
在 config/autoload/dependencies.php 中配置:
return [
Hyperf\Validation\Contract\ValidatorFactoryInterface::class => function ($container) {
$validatorFactory = $container->make(\Hyperf\Validation\Factory::class);
// 添加自定义规则
$validatorFactory->extend('phone', function ($attribute, $value, $parameters, $validator) {
return preg_match('/^1[3-9]\d{9}$/', $value);
});
return $validatorFactory;
},
];
通用注意事项
- 规则优先级:自定义规则通常只影响当前验证,不会覆盖框架内置规则。
- 错误消息国际化:在 Laravel 中,可以在
resources/lang/xx/validation.php添加自定义错误消息; 在 ThinkPHP 中通过验证器$message属性或lang()函数处理。 - 参数传递:Laravel 和 Hyperf 支持从规则中获取参数(如
min:5中的 5),通过$parameters数组访问。 - 性能考虑:对于复杂规则(如数据库查询),建议使用 Laravel 的规则类或 Symfony 的约束验证器,避免闭包中的重复代码。
选择哪种方式取决于你的项目需求和框架版本,对于新项目,建议使用框架推荐的官方扩展方式(如 Laravel 的 Rule 类、ThinkPHP 的验证器方法),以保证代码清晰和可维护性。