本文目录导读:

在PHP项目中,实现表单验证规则的复用封装,通常有几种主流且成熟的模式,我会从最基础的函数封装,到较为高级的类封装,推荐几种实用方案。
基础函数封装
简单的验证函数集
<?php
// validators.php
function validateRequired($value, $fieldName = '') {
if (empty(trim($value))) {
return "$fieldName 不能为空";
}
return true;
}
function validateEmail($value, $fieldName = '') {
if (!filter_var($value, FILTER_VALIDATE_EMAIL)) {
return "$fieldName 格式不正确";
}
return true;
}
function validateMinLength($value, $min, $fieldName = '') {
if (mb_strlen($value) < $min) {
return "$fieldName 至少需要 $min 个字符";
}
return true;
}
function validateMaxLength($value, $max, $fieldName = '') {
if (mb_strlen($value) > $max) {
return "$fieldName 不能超过 $max 个字符";
}
return true;
}
function validateNumeric($value, $fieldName = '') {
if (!is_numeric($value)) {
return "$fieldName 必须是数字";
}
return true;
}
验证规则执行器
<?php
// validator.php
function validate($data, $rules) {
$errors = [];
foreach ($rules as $field => $ruleSet) {
$value = $data[$field] ?? '';
$fieldName = $ruleSet['label'] ?? $field;
foreach ($ruleSet as $rule => $param) {
if ($rule === 'label') continue;
$result = applyRule($rule, $value, $param, $fieldName);
if ($result !== true) {
$errors[$field][] = $result;
break; // 一条规则失败就不再检查其他规则
}
}
}
return $errors;
}
function applyRule($rule, $value, $param, $fieldName) {
switch ($rule) {
case 'required':
return validateRequired($value, $fieldName);
case 'email':
return validateEmail($value, $fieldName);
case 'min':
return validateMinLength($value, $param, $fieldName);
case 'max':
return validateMaxLength($value, $param, $fieldName);
case 'numeric':
return validateNumeric($value, $fieldName);
default:
return true;
}
}
使用示例
<?php
// 调用
$data = [
'username' => 'john',
'email' => 'invalid-email',
'age' => 'abc'
];
$rules = [
'username' => [
'label' => '用户名',
'required' => true,
'min' => 3,
'max' => 20
],
'email' => [
'label' => '邮箱',
'required' => true,
'email' => true
],
'age' => [
'label' => '年龄',
'required' => true,
'numeric' => true
]
];
$errors = validate($data, $rules);
print_r($errors);
面向对象封装
验证规则类
<?php
// Rule.php
abstract class Rule {
protected $message;
public function __construct($message = null) {
$this->message = $message;
}
abstract public function validate($value): bool;
public function message($fieldName): string {
return $this->message ?? "{$fieldName} 验证失败";
}
}
class Required extends Rule {
public function validate($value): bool {
return !empty(trim($value));
}
public function message($fieldName): string {
return $this->message ?? "{$fieldName} 不能为空";
}
}
class Email extends Rule {
public function validate($value): bool {
return filter_var($value, FILTER_VALIDATE_EMAIL) !== false;
}
public function message($fieldName): string {
return $this->message ?? "{$fieldName} 格式不正确";
}
}
class MinLength extends Rule {
private $min;
public function __construct($min, $message = null) {
$this->min = $min;
parent::__construct($message);
}
public function validate($value): bool {
return mb_strlen($value) >= $this->min;
}
public function message($fieldName): string {
return $this->message ?? "{$fieldName} 至少需要 {$this->min} 个字符";
}
}
验证器类
<?php
// Validator.php
class Validator {
private $data;
private $rules = [];
private $errors = [];
public function __construct(array $data) {
$this->data = $data;
}
public function addRule(string $field, Rule $rule, string $fieldName = null) {
$this->rules[] = [
'field' => $field,
'rule' => $rule,
'fieldName' => $fieldName ?? $field
];
return $this; // 链式调用支持
}
public function validate(): bool {
$this->errors = [];
foreach ($this->rules as $ruleSet) {
$value = $this->data[$ruleSet['field']] ?? '';
if (!$ruleSet['rule']->validate($value)) {
$this->errors[$ruleSet['field']][] =
$ruleSet['rule']->message($ruleSet['fieldName']);
}
}
return empty($this->errors);
}
public function getErrors(): array {
return $this->errors;
}
}
使用示例
<?php
// 使用
$data = [
'username' => '',
'email' => 'invalid',
'password' => '123'
];
$validator = new Validator($data);
$validator
->addRule('username', new Required(), '用户名')
->addRule('username', new MinLength(3), '用户名')
->addRule('email', new Required(), '邮箱')
->addRule('email', new Email(), '邮箱')
->addRule('password', new MinLength(6), '密码');
if ($validator->validate()) {
echo "验证通过";
} else {
print_r($validator->getErrors());
}
使用现有库(推荐)
对于生产环境,推荐使用成熟的开源验证库:
respect/validation
<?php
use Respect\Validation\Validator as v;
$validator = v::attribute('username', v::alnum()->length(3, 20))
->attribute('email', v::email())
->attribute('age', v::intVal()->between(18, 100));
try {
$validator->assert($data);
echo "验证通过";
} catch (\Respect\Validation\Exceptions\NestedValidationException $e) {
print_r($e->getMessages());
}
symfony/validator
<?php
use Symfony\Component\Validator\Validation;
use Symfony\Component\Validator\Constraints as Assert;
$validator = Validation::createValidator();
$constraints = new Assert\Collection([
'username' => [
new Assert\NotBlank(['message' => '用户名不能为空']),
new Assert\Length(['min' => 3, 'max' => 20])
],
'email' => new Assert\Email(),
'age' => new Assert\Range(['min' => 18, 'max' => 100])
]);
$violations = $validator->validate($data, $constraints);
if (count($violations) > 0) {
foreach ($violations as $violation) {
echo $violation->getMessage();
}
}
高级封装:规则组合与自定义
支持规则组合
<?php
// 组合验证
$validator->addRule('password', new Required())
->addRule('password', new MinLength(8))
->addRule('password', new Regex('/[A-Z]/', '密码必须包含大写字母'))
->addRule('password', new Regex('/[0-9]/', '密码必须包含数字'));
// 或者使用 OR 组合
$validator->addRule('phone', new AnyOf([
new Phone(),
new Email()
], '请输入有效的手机号或邮箱'));
条件验证
<?php
class RequiredIf extends Rule {
private $condition;
public function __construct(callable $condition, $message = null) {
$this->condition = $condition;
parent::__construct($message);
}
public function validate($value): bool {
if (($this->condition)()) {
return !empty(trim($value));
}
return true; // 条件不满足时不验证
}
}
总结与建议
- 简单项目:使用基础函数封装即可
- 中型项目:推荐面向对象封装
- 大型项目:强烈建议使用 Symfony Validator 或 Respect Validation 等成熟库
- 性能考虑:注意使用缓存,避免重复创建验证规则实例
- 国际化:规则消息支持多语言配置
选择哪种方案取决于项目规模和复杂度,但始终建议遵循 DRY(Don't Repeat Yourself) 原则,将验证逻辑集中管理。
版权声明: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直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播