Laravel 自定义验证规则的“组合拳”与“条件分支”讲座
各位老铁们,大家好!今天咱们来聊聊 Laravel 中自定义验证规则的那些事儿。别看这玩意儿名字高大上,其实它就像你家楼下卖煎饼果子的大爷一样平易近人。只要你掌握了它的套路,分分钟让你的表单验证变得优雅又高效。
准备好了吗?那咱们就开讲啦!
讲座大纲
- 什么是自定义验证规则?
- 如何创建和使用自定义验证规则?
- 验证规则的“组合拳”:多个规则一起用
- 验证逻辑的“条件分支”:根据场景动态调整
- 实战演练:一个复杂的表单验证案例
- 总结 & Q&A
1. 什么是自定义验证规则?
在 Laravel 中,默认提供了很多现成的验证规则(比如 required
、email
、min
等),但有时候这些规则并不能完全满足我们的需求。这时候,就需要我们自己动手,丰衣足食——也就是创建自定义验证规则。
简单来说,自定义验证规则就是一种扩展机制,让我们可以定义自己的验证逻辑。举个栗子,假如你想验证用户输入的密码是否包含至少一个特殊字符,Laravel 默认是没有这个规则的,但我们可以轻松实现它。
2. 如何创建和使用自定义验证规则?
方法一:使用匿名函数(Closure)
这是最简单的自定义验证方式。直接在验证规则中传入一个 Closure 函数即可。
$validator = Validator::make($request->all(), [
'password' => [
'required',
function ($attribute, $value, $fail) {
if (!preg_match('/[!@#$%^&*]/', $value)) {
$fail($attribute . ' 必须包含至少一个特殊字符。');
}
},
],
]);
小贴士:这种方式适合简单的场景,但如果规则复杂或者需要复用,建议用下面的方法。
方法二:使用 Rule 对象
Laravel 提供了一个 Rule
类,可以用来封装更复杂的验证逻辑。
use IlluminateValidationRule;
$validator = Validator::make($request->all(), [
'password' => [
'required',
new Rule(function ($attribute, $value, $fail) {
if (!preg_match('/[!@#$%^&*]/', $value)) {
$fail('密码必须包含至少一个特殊字符。');
}
}),
],
]);
方法三:自定义验证规则类
如果你觉得上面两种方法还不够优雅,那就试试创建一个独立的验证规则类吧!
步骤 1:生成规则类
php artisan make:rule PasswordContainsSpecialCharacter
步骤 2:实现验证逻辑
打开生成的类文件(app/Rules/PasswordContainsSpecialCharacter.php
),实现 passes
和 message
方法。
namespace AppRules;
use IlluminateContractsValidationRule;
class PasswordContainsSpecialCharacter implements Rule
{
public function passes($attribute, $value)
{
return preg_match('/[!@#$%^&*]/', $value);
}
public function message()
{
return '密码必须包含至少一个特殊字符。';
}
}
步骤 3:使用规则类
$validator = Validator::make($request->all(), [
'password' => ['required', new PasswordContainsSpecialCharacter()],
]);
3. 验证规则的“组合拳”:多个规则一起用
很多时候,我们需要对同一个字段应用多个验证规则。比如,用户名必须是唯一的,同时长度不能超过 20 个字符。
$validator = Validator::make($request->all(), [
'username' => [
'required',
'string',
'max:20',
Rule::unique('users'),
],
]);
小贴士:规则的顺序很重要!如果某个规则失败了,后面的规则就不会再执行了。所以,把耗时的规则(比如数据库查询)放在最后。
4. 验证逻辑的“条件分支”:根据场景动态调整
有时候,验证规则需要根据不同的场景动态变化。比如,注册时需要验证邮箱是否唯一,而登录时只需要验证邮箱是否存在。
使用 sometimes
方法
$validator = Validator::make($request->all(), [
'email' => 'required|email',
]);
if ($action === 'register') {
$validator->sometimes('email', 'unique:users', function ($input) {
return !empty($input->email);
});
} elseif ($action === 'login') {
$validator->sometimes('email', 'exists:users', function ($input) {
return !empty($input->email);
});
}
使用 when
方法
Laravel 9+ 提供了更简洁的 when
方法:
$validator = Validator::make($request->all(), [
'email' => 'required|email',
]);
$validator->sometimes('email', 'unique:users', function () use ($action) {
return $action === 'register';
});
$validator->sometimes('email', 'exists:users', function () use ($action) {
return $action === 'login';
});
5. 实战演练:一个复杂的表单验证案例
假设我们要实现一个用户注册表单,要求如下:
- 用户名必须是唯一的,且长度不超过 20 个字符。
- 密码必须包含至少一个大写字母、一个小写字母和一个数字。
- 如果用户选择了“记住我”选项,则需要额外验证验证码。
use AppRulesPasswordComplexity;
use IlluminateSupportFacadesValidator;
$validator = Validator::make($request->all(), [
'username' => ['required', 'string', 'max:20', Rule::unique('users')],
'password' => ['required', new PasswordComplexity()],
]);
if ($request->has('remember_me')) {
$validator->sometimes('captcha', 'required|captcha', function ($input) {
return true;
});
}
if ($validator->fails()) {
return redirect()->back()->withErrors($validator)->withInput();
}
其中,PasswordComplexity
是一个自定义规则类:
namespace AppRules;
use IlluminateContractsValidationRule;
class PasswordComplexity implements Rule
{
public function passes($attribute, $value)
{
return preg_match('/[A-Z]/', $value) && // 至少一个大写字母
preg_match('/[a-z]/', $value) && // 至少一个小写字母
preg_match('/[0-9]/', $value); // 至少一个数字
}
public function message()
{
return '密码必须包含至少一个大写字母、一个小写字母和一个数字。';
}
}
6. 总结 & Q&A
今天的讲座就到这里啦!我们学习了以下内容:
- 如何创建和使用自定义验证规则(Closure、Rule 对象、规则类)。
- 如何将多个规则组合在一起。
- 如何根据场景动态调整验证逻辑。
如果有任何疑问,欢迎在评论区提问!我会像 Stack Overflow 的大神一样,为你解答困惑 。
最后,送给大家一句话:"Validation is not just about rules; it’s about making your application more robust and user-friendly." —— Laravel 官方文档
下次见咯!