Laravel 自定义验证规则的验证规则的依赖注入策略与验证逻辑的条件分支方法

🎤 Laravel 自定义验证规则:依赖注入与条件分支的艺术

各位小伙伴,今天咱们来聊聊 Laravel 验证规则中的“高级玩法”——自定义验证规则的依赖注入策略和验证逻辑的条件分支方法。这可是让代码更优雅、更灵活的秘密武器!😎


📝 讲座大纲

  1. 什么是自定义验证规则?
  2. 依赖注入在验证规则中的应用
  3. 如何用条件分支优化验证逻辑
  4. 案例实战:一个完整的自定义验证规则

1. 什么是自定义验证规则?

Laravel 提供了丰富的内置验证规则(如 requiredemail 等),但有时候这些规则并不能完全满足我们的需求。这时,我们就可以创建自己的验证规则。

Laravel 提供了两种方式来实现自定义验证规则:

  • 使用闭包函数
  • 创建独立的规则类

示例:使用闭包函数

Validator::make($data, [
    'age' => function ($attribute, $value, $fail) {
        if ($value < 18) {
            $fail('你必须年满 18 岁才能参加这个活动 😢');
        }
    },
]);

虽然闭包函数简单易用,但它缺乏灵活性和可复用性。接下来,我们看看如何通过规则类来实现更强大的功能。


2. 依赖注入在验证规则中的应用

Laravel 的验证规则类可以通过实现 IlluminateContractsValidationRule 接口来创建。这种规则类的一个强大之处在于,它可以利用 Laravel 的服务容器进行依赖注入。

步骤:

  1. 创建一个规则类。
  2. 在构造函数中注入所需的依赖。
  3. 实现 passesmessage 方法。

示例:创建一个规则类

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. 案例实战:一个完整的自定义验证规则

假设我们要开发一个功能,允许用户上传头像,但需要满足以下条件:

  1. 文件类型必须是图片。
  2. 文件大小不能超过 2MB。
  3. 如果用户是 VIP,则可以上传任意大小的图片。

解决方案:

  1. 创建一个规则类 AvatarValidation
  2. 在规则类中实现依赖注入和条件分支。

代码实现:

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 的验证系统有更深的理解!如果有任何问题,欢迎在评论区留言 ❤️。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注