PHP项目框架验证器如何自定义规则

wen PHP项目 20

本文目录导读:

PHP项目框架验证器如何自定义规则

  1. Laravel 框架
  2. ThinkPHP 6.0/8.0 框架
  3. Symfony 框架(使用约束组件)
  4. Hyperf 框架
  5. 通用注意事项

在PHP项目中,自定义验证规则是框架验证器非常重要的功能扩展点,不同框架的实现方式略有不同,下面以主流的 LaravelThinkPHPSymfonyHyperf 为例,介绍如何自定义验证规则。


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 类(全局生效)

AppServiceProviderboot 方法中:

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.phpservice.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;
    },
];

通用注意事项

  1. 规则优先级:自定义规则通常只影响当前验证,不会覆盖框架内置规则。
  2. 错误消息国际化:在 Laravel 中,可以在 resources/lang/xx/validation.php 添加自定义错误消息; 在 ThinkPHP 中通过验证器 $message 属性或 lang() 函数处理。
  3. 参数传递:Laravel 和 Hyperf 支持从规则中获取参数(如 min:5 中的 5),通过 $parameters 数组访问。
  4. 性能考虑:对于复杂规则(如数据库查询),建议使用 Laravel 的规则类或 Symfony 的约束验证器,避免闭包中的重复代码。

选择哪种方式取决于你的项目需求和框架版本,对于新项目,建议使用框架推荐的官方扩展方式(如 Laravel 的 Rule 类、ThinkPHP 的验证器方法),以保证代码清晰和可维护性。

抱歉,评论功能暂时关闭!