ThinkPHP框架内置了验证器功能,能够帮助开发者快速完成请求数据的合法性校验,避免无效数据进入业务逻辑层,减少手动校验的重复代码。验证器的核心是通过定义规则集合,对传入的数组数据进行批量校验,同时支持自定义错误提示和校验逻辑。
验证器基础编写方式
ThinkPHP的验证器需要继承thinkValidate类,在验证器类中定义$rule属性存储校验规则,$message属性存储错误提示信息,$scene属性定义校验场景。
以下是一个基础的用户验证器示例,用于校验用户注册时的提交数据:
<?php
namespace appvalidate;
use thinkValidate;
class UserValidate extends Validate
{
// 定义校验规则
protected $rule = [
'username' => 'require|length:4,20|alphaNum',
'password' => 'require|length:6,20',
'email' => 'require|email',
'mobile' => 'require|mobile',
];
// 定义错误提示
protected $message = [
'username.require' => '用户名不能为空',
'username.length' => '用户名长度需在4到20个字符之间',
'username.alphaNum' => '用户名只能包含字母和数字',
'password.require' => '密码不能为空',
'password.length' => '密码长度需在6到20个字符之间',
'email.require' => '邮箱不能为空',
'email.email' => '邮箱格式不正确',
'mobile.require' => '手机号不能为空',
'mobile.mobile' => '手机号格式不正确',
];
// 定义校验场景
protected $scene = [
'register' => ['username', 'password', 'email', 'mobile'],
'login' => ['username', 'password'],
];
}
内置校验规则说明
ThinkPHP内置了大量常用的校验规则,开发者可以直接在$rule属性中调用,无需重复开发。常用的内置规则如下:
- require:验证字段必须存在且不为空
- email:验证字段符合邮箱格式
- mobile:验证字段符合手机号格式
- length:min,max:验证字段长度在指定区间内
- alphaNum:验证字段只包含字母和数字
- number:验证字段为数字类型
- in:value1,value2:验证字段值在指定枚举范围内
- gt:value:验证字段值大于指定数值
自定义校验规则开发
如果内置规则无法满足业务需求,开发者可以自定义校验规则,自定义规则有两种实现方式:在验证器类中定义规则方法,或者定义闭包规则。
验证器类内定义规则方法
规则方法的命名格式为check+规则名首字母大写,方法接收两个参数,第一个是待校验的值,第二个是规则参数,返回布尔值表示校验是否通过。
以下示例实现了一个校验用户名是否已存在的自定义规则:
<?php
namespace appvalidate;
use thinkValidate;
use appmodelUser;
class UserValidate extends Validate
{
protected $rule = [
'username' => 'require|checkUniqueUsername',
];
protected $message = [
'username.require' => '用户名不能为空',
'username.checkUniqueUsername' => '用户名已存在',
];
// 自定义校验规则:检查用户名是否唯一
protected function checkUniqueUsername($value)
{
$count = User::where('username', $value)->count();
return $count === 0;
}
}
闭包方式定义规则
对于简单的自定义规则,可以直接在$rule属性中使用闭包定义,闭包接收待校验值和完整数据数组两个参数。
<?php
namespace appvalidate;
use thinkValidate;
class OrderValidate extends Validate
{
protected $rule = [
'pay_amount' => [
'require',
function($value, $data) {
// 校验支付金额不能小于订单最低金额
return $value >= 0.01 ? true : '支付金额不能小于0.01元';
}
],
];
}
数据校验实战示例
编写好验证器之后,在控制器中调用验证器完成数据校验,以下是用户注册场景的完整校验流程:
<?php
namespace appcontroller;
use appvalidateUserValidate;
use thinkexceptionValidateException;
use thinkRequest;
class User
{
public function register(Request $request)
{
$data = $request->post();
try {
// 调用验证器的register场景进行校验
validate(UserValidate::class)->scene('register')->check($data);
// 校验通过,执行后续注册逻辑
// ...
return json(['code' => 200, 'msg' => '注册成功']);
} catch (ValidateException $e) {
// 校验失败,返回错误信息
return json(['code' => 400, 'msg' => $e->getError()]);
}
}
}
如果需要批量获取所有校验错误,而不是遇到第一个错误就返回,可以设置验证器的batch模式:
<?php
validate(UserValidate::class)->scene('register')->batch(true)->check($data);
校验失败时会抛出异常,异常对象的getError()方法在批量模式下会返回所有错误信息的数组,方便前端统一展示。