🎤 Laravel 自定义验证规则:依赖注入与条件分支的艺术
各位小伙伴,今天咱们来聊聊 Laravel 验证规则中的“高级玩法”——自定义验证规则的依赖注入策略和验证逻辑的条件分支方法。这可是让代码更优雅、更灵活的秘密武器!😎
📝 讲座大纲
- 什么是自定义验证规则?
- 依赖注入在验证规则中的应用
- 如何用条件分支优化验证逻辑
- 案例实战:一个完整的自定义验证规则
1. 什么是自定义验证规则?
Laravel 提供了丰富的内置验证规则(如 required
、email
等),但有时候这些规则并不能完全满足我们的需求。这时,我们就可以创建自己的验证规则。
Laravel 提供了两种方式来实现自定义验证规则:
- 使用闭包函数
- 创建独立的规则类
示例:使用闭包函数
Validator::make($data, [
'age' => function ($attribute, $value, $fail) {
if ($value < 18) {
$fail('你必须年满 18 岁才能参加这个活动 😢');
}
},
]);
虽然闭包函数简单易用,但它缺乏灵活性和可复用性。接下来,我们看看如何通过规则类来实现更强大的功能。
2. 依赖注入在验证规则中的应用
Laravel 的验证规则类可以通过实现 IlluminateContractsValidationRule
接口来创建。这种规则类的一个强大之处在于,它可以利用 Laravel 的服务容器进行依赖注入。
步骤:
- 创建一个规则类。
- 在构造函数中注入所需的依赖。
- 实现
passes
和message
方法。
示例:创建一个规则类
use IlluminateContractsValidationRule;
class AgeValidation implements Rule
{
protected $minimumAge;
public function __construct($minimumAge)
{
$this->minimumAge = $minimumAge;
}
public function passes($attribute, $value)
{
return $value >= $this->minimumAge;
}
public function message()
{
return '你必须年满 :min 岁才能参加这个活动 😢';
}
}
使用规则类
$validator = Validator::make($request->all(), [
'age' => [new AgeValidation(18)],
]);
依赖注入的作用:
- 我们可以在构造函数中注入任何服务或配置。
- 比如,如果最低年龄是从数据库中动态获取的,我们可以这样写:
use AppServicesAgeConfiguration;
class AgeValidation implements Rule
{
protected $minimumAge;
public function __construct(AgeConfiguration $config)
{
$this->minimumAge = $config->getMinimumAge();
}
// 其他方法省略...
}
💡 小贴士:依赖注入让规则类更加灵活和可测试。你可以轻松地替换依赖项,甚至在单元测试中模拟它们。
3. 如何用条件分支优化验证逻辑?
有时候,我们需要根据不同的条件来调整验证逻辑。例如,验证用户是否可以更新他们的资料时,可能需要检查用户的权限级别。
方法一:直接在 passes
方法中添加条件分支
public function passes($attribute, $value)
{
if (auth()->user()->isAdmin()) {
return true; // 管理员无需验证
}
return $value >= $this->minimumAge;
}
方法二:使用多个规则类组合
Laravel 支持将多个规则组合在一起。我们可以为不同的条件创建不同的规则类,并在验证时按需使用。
示例:管理员和普通用户的年龄验证
$rules = auth()->user()->isAdmin()
? ['age' => []] // 管理员无需验证
: ['age' => [new AgeValidation(18)]];
$validator = Validator::make($request->all(), $rules);
方法三:动态生成规则
如果你有复杂的条件逻辑,可以考虑动态生成规则。例如,根据用户的性别设置不同的最低年龄要求。
$rules = [
'age' => [
new AgeValidation(
$request->input('gender') === 'male'
? config('app.min_age_male')
: config('app.min_age_female')
),
],
];
4. 案例实战:一个完整的自定义验证规则
假设我们要开发一个功能,允许用户上传头像,但需要满足以下条件:
- 文件类型必须是图片。
- 文件大小不能超过 2MB。
- 如果用户是 VIP,则可以上传任意大小的图片。
解决方案:
- 创建一个规则类
AvatarValidation
。 - 在规则类中实现依赖注入和条件分支。
代码实现:
use IlluminateContractsValidationRule;
use IlluminateSupportFacadesAuth;
class AvatarValidation implements Rule
{
public function passes($attribute, $value)
{
if (!in_array($value->getClientMimeType(), ['image/jpeg', 'image/png'])) {
return false; // 不是图片类型
}
if (Auth::user()->isVIP()) {
return true; // VIP 用户不限制大小
}
return $value->getSize() <= 2 * 1024 * 1024; // 普通用户限制为 2MB
}
public function message()
{
if (Auth::user()->isVIP()) {
return '文件类型必须是图片 🖼️';
}
return '文件类型必须是图片,且大小不能超过 2MB 🖼️';
}
}
使用规则类:
$validator = Validator::make($request->all(), [
'avatar' => [new AvatarValidation()],
]);
总结
今天的讲座到这里就结束了!🎉 我们学习了如何通过依赖注入让验证规则更灵活,以及如何使用条件分支优化验证逻辑。以下是关键点回顾:
- 依赖注入:让规则类可以轻松访问服务容器中的依赖。
- 条件分支:根据不同的场景动态调整验证逻辑。
- 组合规则:通过多个规则类的组合实现复杂的验证需求。
希望这篇文章能让你对 Laravel 的验证系统有更深的理解!如果有任何问题,欢迎在评论区留言 ❤️。