Respect/Validation 自定义验证规则开发指南
前言
在 PHP 开发中,数据验证是保证应用安全性和数据完整性的重要环节。Respect/Validation 作为一个强大的验证库,提供了丰富的内置验证规则。但实际开发中,我们经常需要根据业务需求创建自定义验证规则。本文将详细介绍如何在 Respect/Validation 中创建和使用自定义验证规则。
自定义规则的基本结构
每个自定义规则由两部分组成:
- 规则类 - 包含实际的验证逻辑
- 异常类 - 定义验证失败时的错误信息
规则类开发
规则类需要继承 Simple
抽象类,并实现 isValid
方法:
namespace My\Validation\Rules;
use Respect\Validation\Rules\Core\Simple;
final class IsEvenNumber extends Simple
{
public function isValid(mixed $input): bool
{
// 验证输入是否为偶数
if (!is_numeric($input)) {
return false;
}
return $input % 2 === 0;
}
}
关键点:
- 类名使用单数形式
- 必须实现
isValid
方法,返回布尔值 - 方法参数
$input
为待验证的值
异常类开发
异常类需要继承 ValidationException
,并定义验证失败时的提示信息:
namespace My\Validation\Exceptions;
use Respect\Validation\Exceptions\ValidationException;
final class IsEvenNumberException extends ValidationException
{
protected $defaultTemplates = [
self::MODE_DEFAULT => [
self::STANDARD => '{{name}} 必须是偶数',
],
self::MODE_NEGATIVE => [
self::STANDARD => '{{name}} 不能是偶数',
],
];
}
说明:
- 异常类名 = 规则类名 + "Exception"
MODE_DEFAULT
是普通验证失败时的消息MODE_NEGATIVE
是使用not()
否定规则时的消息{{name}}
是占位符,会被实际字段名替换
项目结构规范
建议采用以下目录结构组织自定义规则:
项目目录
+-- Validation
+-- Exceptions
+-- IsEvenNumberException.php
+-- OtherException.php
+-- Rules
+-- IsEvenNumber.php
+-- Other.php
注意:
- 目录名使用复数形式(Rules/Exceptions)
- 类名使用单数形式
- 保持规则和异常一一对应
注册自定义规则
创建规则后,需要配置工厂类才能使用:
use Respect\Validation\Factory;
Factory::setDefaultInstance(
(new Factory())
->withRuleNamespace('My\\Validation\\Rules')
->withExceptionNamespace('My\\Validation\\Exceptions')
);
配置后即可像内置规则一样使用:
use Respect\Validation\Validator as v;
$validator = v::isEvenNumber();
$validator->validate(2); // true
$validator->validate(3); // false, 触发IsEvenNumberException
最佳实践建议
- 单一职责原则:每个规则只负责一个具体的验证逻辑
- 明确错误信息:异常消息应清晰说明验证要求
- 类型检查:验证前应先检查输入类型是否合法
- 性能考虑:复杂验证逻辑应考虑性能影响
- 测试覆盖:为自定义规则编写单元测试
高级用法
带参数的规则
可以创建需要参数的规则:
final class DivisibleBy extends Simple
{
public function __construct(private int $number) {}
public function isValid(mixed $input): bool
{
return is_numeric($input) && $input % $this->number === 0;
}
}
使用方式:
v::divisibleBy(3)->validate(9); // true
复合规则
可以在自定义规则中使用其他规则:
final class ValidEmailOrPhone extends Simple
{
public function isValid(mixed $input): bool
{
return v::email()->validate($input)
|| v::phone()->validate($input);
}
}
常见问题解决
- 规则未生效:检查工厂配置的命名空间是否正确
- 错误信息不显示:确保异常类路径和命名正确
- 性能问题:避免在规则中进行复杂数据库查询
- 多语言支持:可在异常类中实现多语言消息
总结
通过自定义规则,可以扩展 Respect/Validation 的功能以满足特定业务需求。关键步骤包括创建规则类、定义异常类、配置工厂。良好的自定义规则应该职责单一、错误信息明确,并且经过充分测试。掌握自定义规则开发技巧,可以大大提高数据验证的灵活性和代码复用性。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考