本文目录导读:

我来为您设计一个PHP验证器工厂模式的完整实现,包含示例和说明。
验证器接口
<?php
// ValidatorInterface.php
namespace App\Validators;
interface ValidatorInterface
{
/**
* 执行验证逻辑
* @param mixed $value 待验证的值
* @param array $options 验证选项
* @return bool 验证是否通过
*/
public function validate($value, array $options = []): bool;
/**
* 获取验证失败的错误消息
* @return string
*/
public function getMessage(): string;
/**
* 设置错误消息
* @param string $message
* @return self
*/
public function setMessage(string $message): self;
}
具体验证器实现
<?php
// RequiredValidator.php
namespace App\Validators;
class RequiredValidator implements ValidatorInterface
{
private $message = '该字段是必填的';
public function validate($value, array $options = []): bool
{
if (isset($options['message'])) {
$this->setMessage($options['message']);
}
if ($value === null || $value === '') {
return false;
}
if (is_array($value) && empty($value)) {
return false;
}
return true;
}
public function getMessage(): string
{
return $this->message;
}
public function setMessage(string $message): self
{
$this->message = $message;
return $this;
}
}
<?php
// EmailValidator.php
namespace App\Validators;
class EmailValidator implements ValidatorInterface
{
private $message = '邮箱格式不正确';
public function validate($value, array $options = []): bool
{
if (isset($options['message'])) {
$this->setMessage($options['message']);
}
if (empty($value)) {
return true; // 可选字段,如果必填则使用 RequiredValidator
}
return filter_var($value, FILTER_VALIDATE_EMAIL) !== false;
}
public function getMessage(): string
{
return $this->message;
}
public function setMessage(string $message): self
{
$this->message = $message;
return $this;
}
}
<?php
// LengthValidator.php
namespace App\Validators;
class LengthValidator implements ValidatorInterface
{
private $message = '长度不符合要求';
public function validate($value, array $options = []): bool
{
$min = $options['min'] ?? 0;
$max = $options['max'] ?? PHP_INT_MAX;
if (isset($options['message'])) {
$this->setMessage($options['message']);
}
$length = mb_strlen($value, 'UTF-8');
if ($length < $min) {
$this->setMessage("长度不能小于 {$min} 个字符");
return false;
}
if ($length > $max) {
$this->setMessage("长度不能大于 {$max} 个字符");
return false;
}
return true;
}
public function getMessage(): string
{
return $this->message;
}
public function setMessage(string $message): self
{
$this->message = $message;
return $this;
}
}
<?php
// NumericValidator.php
namespace App\Validators;
class NumericValidator implements ValidatorInterface
{
private $message = '必须是数字';
public function validate($value, array $options = []): bool
{
if (isset($options['message'])) {
$this->setMessage($options['message']);
}
if (!is_numeric($value)) {
return false;
}
// 检查范围
if (isset($options['min']) && $value < $options['min']) {
$this->setMessage("数字不能小于 {$options['min']}");
return false;
}
if (isset($options['max']) && $value > $options['max']) {
$this->setMessage("数字不能大于 {$options['max']}");
return false;
}
return true;
}
public function getMessage(): string
{
return $this->message;
}
public function setMessage(string $message): self
{
$this->message = $message;
return $this;
}
}
<?php
// RegexValidator.php
namespace App\Validators;
class RegexValidator implements ValidatorInterface
{
private $message = '格式不正确';
public function validate($value, array $options = []): bool
{
if (!isset($options['pattern'])) {
throw new \InvalidArgumentException('正则表达式验证器需要提供pattern选项');
}
if (isset($options['message'])) {
$this->setMessage($options['message']);
}
return preg_match($options['pattern'], $value) === 1;
}
public function getMessage(): string
{
return $this->message;
}
public function setMessage(string $message): self
{
$this->message = $message;
return $this;
}
}
验证器工厂
<?php
// ValidatorFactory.php
namespace App\Validators;
use InvalidArgumentException;
class ValidatorFactory
{
/**
* @var array 验证器别名映射
*/
private static $aliases = [
'required' => RequiredValidator::class,
'email' => EmailValidator::class,
'length' => LengthValidator::class,
'numeric' => NumericValidator::class,
'integer' => NumericValidator::class,
'regex' => RegexValidator::class,
];
/**
* @var array 已创建的验证器实例缓存
*/
private static $instances = [];
/**
* 创建验证器实例
* @param string $type 验证器类型
* @param array $options 验证器选项
* @return ValidatorInterface
* @throws InvalidArgumentException
*/
public static function create(string $type, array $options = []): ValidatorInterface
{
$class = self::resolveClass($type);
// 使用选项作为缓存键的一部分
$cacheKey = $type . ':' . md5(json_encode($options));
if (!isset(self::$instances[$cacheKey])) {
self::$instances[$cacheKey] = new $class();
}
return self::$instances[$cacheKey];
}
/**
* 解析验证器类名
* @param string $type
* @return string
* @throws InvalidArgumentException
*/
private static function resolveClass(string $type): string
{
$type = strtolower($type);
if (isset(self::$aliases[$type])) {
return self::$aliases[$type];
}
// 尝试按类名解析(支持App\Validators\CustomValidator格式)
$class = 'App\\Validators\\' . ucfirst($type) . 'Validator';
if (class_exists($class)) {
return $class;
}
throw new InvalidArgumentException("未知的验证器类型: {$type}");
}
/**
* 注册自定义验证器
* @param string $alias 别名
* @param string $class 类名
* @throws InvalidArgumentException
*/
public static function register(string $alias, string $class): void
{
if (!class_exists($class) || !in_array(ValidatorInterface::class, class_implements($class))) {
throw new InvalidArgumentException("{$class} 必须实现 ValidatorInterface");
}
self::$aliases[strtolower($alias)] = $class;
}
/**
* 清理实例缓存
*/
public static function clearCache(): void
{
self::$instances = [];
}
}
验证器管理器(集成多个验证器)
<?php
// ValidationManager.php
namespace App\Validators;
class ValidationManager
{
private $rules = [];
private $data = [];
private $errors = [];
public function __construct(array $data = [])
{
$this->data = $data;
}
/**
* 添加验证规则
* @param string $field 字段名
* @param string $validator 验证器类型
* @param array $options 验证选项
* @return self
*/
public function addRule(string $field, string $validator, array $options = []): self
{
$this->rules[$field][] = [
'validator' => $validator,
'options' => $options
];
return $this;
}
/**
* 批量添加验证规则
* @param array $rules 格式: ['字段名' => [['validator' => 'required'], ...]]
* @return self
*/
public function addRules(array $rules): self
{
foreach ($rules as $field => $fieldRules) {
foreach ($fieldRules as $rule) {
$validator = $rule['validator'] ?? null;
if (!$validator) {
continue;
}
$options = $rule['options'] ?? [];
$this->addRule($field, $validator, $options);
}
}
return $this;
}
/**
* 执行验证
* @return bool
*/
public function validate(): bool
{
$this->errors = [];
foreach ($this->rules as $field => $rules) {
$value = $this->data[$field] ?? null;
foreach ($rules as $rule) {
$validator = ValidatorFactory::create(
$rule['validator'],
$rule['options']
);
if (!$validator->validate($value, $rule['options'])) {
$this->errors[$field][] = $validator->getMessage();
break; // 一个字段只显示第一个错误
}
}
}
return empty($this->errors);
}
/**
* 获取所有错误信息
* @return array
*/
public function getErrors(): array
{
return $this->errors;
}
/**
* 获取指定字段的错误信息
* @param string $field
* @return array
*/
public function getFieldErrors(string $field): array
{
return $this->errors[$field] ?? [];
}
}
使用示例
<?php
// usage.php
require 'vendor/autoload.php';
use App\Validators\ValidatorFactory;
use App\Validators\ValidationManager;
use App\Validators\CustomValidators\PhoneValidator;
// 1. 基本用法
$emailValidator = ValidatorFactory::create('email');
$isValid = $emailValidator->validate('user@example.com');
echo $isValid ? "Email有效\n" : "Email无效\n";
// 2. 带选项的验证
$lengthValidator = ValidatorFactory::create('length', ['min' => 3, 'max' => 10]);
$isValid = $lengthValidator->validate('Hello');
echo $isValid ? "长度有效\n" : "长度无效\n";
// 3. 注册自定义验证器
ValidatorFactory::register('phone', PhoneValidator::class);
// 4. 使用验证管理器
$data = [
'username' => 'JohnDoe',
'email' => 'john@example.com',
'age' => '25',
'phone' => '13800138000'
];
$validationManager = new ValidationManager($data);
$validationManager
->addRule('username', 'required', ['message' => '用户名不能为空'])
->addRule('username', 'length', ['min' => 3, 'max' => 20, 'message' => '用户名长度需在3-20之间'])
->addRule('email', 'required', ['message' => '邮箱不能为空'])
->addRule('email', 'email', ['message' => '邮箱格式不正确'])
->addRule('age', 'numeric', ['min' => 18, 'max' => 100])
->addRule('phone', 'phone', ['message' => '手机号格式不正确']);
if ($validationManager->validate()) {
echo "所有验证通过!\n";
} else {
print_r($validationManager->getErrors());
}
// 5. 批量添加规则示例
$rules = [
'name' => [
['validator' => 'required', 'options' => ['message' => '姓名必填']],
['validator' => 'length', 'options' => ['min' => 2, 'max' => 50, 'message' => '姓名长度需在2-50之间']]
],
'age' => [
['validator' => 'numeric', 'options' => ['min' => 1, 'max' => 150, 'message' => '年龄需在1-150之间']]
]
];
$manager = new ValidationManager([
'name' => 'John',
'age' => 30
]);
$manager->addRules($rules);
if ($manager->validate()) {
echo "批量规则验证通过!\n";
} else {
print_r($manager->getErrors());
}
// 6. 自定义验证器类
// CustomValidators/PhoneValidator.php
namespace App\Validators\CustomValidators;
use App\Validators\ValidatorInterface;
class PhoneValidator implements ValidatorInterface
{
private $message = '手机号格式不正确';
public function validate($value, array $options = []): bool
{
if (isset($options['message'])) {
$this->setMessage($options['message']);
}
if (empty($value)) {
return true;
}
// 中国大陆手机号简单验证
return preg_match('/^1[3-9]\d{9}$/', $value) === 1;
}
public function getMessage(): string
{
return $this->message;
}
public function setMessage(string $message): self
{
$this->message = $message;
return $this;
}
}
高级特性
<?php
// AdvancedValidatorFactory.php - 支持闭包验证器
namespace App\Validators;
class AdvancedValidatorFactory
{
private static $closures = [];
/**
* 注册闭包验证器
* @param string $name
* @param callable $callback 接收值和选项,返回bool
*/
public static function registerClosure(string $name, callable $callback): void
{
self::$closures[$name] = $callback;
}
/**
* 创建闭包验证器
*/
public static function createClosure(string $name, callable $callback): ValidatorInterface
{
return new class($name, $callback) implements ValidatorInterface {
private $name;
private $callback;
private $message;
public function __construct(string $name, callable $callback)
{
$this->name = $name;
$this->callback = $callback;
}
public function validate($value, array $options = []): bool
{
$this->message = $options['message'] ?? "验证失败";
return call_user_func($this->callback, $value, $options);
}
public function getMessage(): string
{
return $this->message;
}
public function setMessage(string $message): self
{
$this->message = $message;
return $this;
}
};
}
}
// 使用闭包验证器
AdvancedValidatorFactory::registerClosure('even', function($value) {
return $value % 2 === 0;
});
$validator = AdvancedValidatorFactory::createClosure('even',
AdvancedValidatorFactory::$closures['even']
);
测试类
<?php
// tests/ValidatorTest.php
use PHPUnit\Framework\TestCase;
use App\Validators\ValidatorFactory;
use App\Validators\ValidationManager;
class ValidatorTest extends TestCase
{
public function testEmailValidation()
{
$validator = ValidatorFactory::create('email');
$this->assertTrue($validator->validate('test@example.com'));
$this->assertFalse($validator->validate('invalid-email'));
}
public function testRequiredValidation()
{
$validator = ValidatorFactory::create('required');
$this->assertFalse($validator->validate(''));
$this->assertFalse($validator->validate(null));
$this->assertTrue($validator->validate('some value'));
}
public function testValidationManager()
{
$data = [
'name' => 'John',
'email' => 'john@example.com'
];
$manager = new ValidationManager($data);
$manager
->addRule('name', 'required')
->addRule('name', 'length', ['min' => 2])
->addRule('email', 'email');
$this->assertTrue($manager->validate());
$this->assertEmpty($manager->getErrors());
}
}
Composer 配置
{
"name": "validator-factory",
"description": "PHP Validator Factory Pattern",
"autoload": {
"psr-4": {
"App\\": "src/"
}
},
"require": {
"php": ">=7.4"
}
}
核心优势
- 灵活扩展:新增验证器只需实现接口并注册
- 代码复用:验证器可重用,避免重复代码
- 配置集中:验证规则配置清晰,易于维护
- 错误处理:统一的错误消息管理
- 性能优化:实例缓存机制
- 开闭原则:对扩展开放,对修改关闭
这个验证器工厂模式适合各种PHP项目,从简单表单验证到复杂的数据校验场景都能很好的支持。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播