【问题标题】:How to avoid duplication in Laravel validation rules如何避免 Laravel 验证规则中的重复
【发布时间】:2019-10-24 13:25:33
【问题描述】:

为了验证表单验证规则,我目前将它们存储在用户模型中,并在注册控制器、管理面板中的用户控制器、API 中的用户控制器和其他一些地方使用它,但目前很难维护,因为每个控制器都需要稍微不同的规则集,当我更改用户模型中的规则时,其他控制器将不再工作。那么如何在避免重复规则的同时保持代码的可维护性呢?

【问题讨论】:

  • 您目前如何构建验证,您是使用 make:request 还是只是在控制器中的所有功能中进行验证?
  • @JellyBean 我在控制器的存储方法中像这样使用$this->validate($request, User::rules());

标签: php laravel validation design-patterns duplicates


【解决方案1】:

我经常使用的方法是为我的模型编写一个HasRules trait,它看起来像这样:

trait HasRules
{
    public static function getValidationRules(): array
    {
        if (! property_exists(static::class, 'rules')) {
            return [];
        }

        if (func_num_args() === 0) {
            return static::$rules;
        }

        if (func_num_args() === 1 && is_string(func_get_arg(0))) {
            return array_get(static::$rules, func_get_arg(0), []);
        }

        $attributes = func_num_args() === 1 && is_array(func_get_arg(0))
            ? func_get_arg(0)
            : func_get_args();

        return array_only(static::$rules, $attributes);
    }
}

看起来很乱,但它的作用是允许您以多种方式检索您的规则(如果存在,则从静态字段中)。因此,在您的模型中,您可以:

class User extends Model
{
    use HasRules;

    public static $rules = [
        'name' => ['required'],
        'age' => ['min:16']
    ];

    ...
}

然后在您的验证中(例如,在您的FormRequestrules() 方法中或在准备规则数组时的控制器中)您可以通过多种方式调用此getValidationRules()

 $allRules = User::getValidationRules(); // if called with no parameters all rules will be returned.

 $onlySomeRules = [
     'controller_specific_field' => ['required'],
     'name' => User::getValidationRules('name'); // if called with one string parameter only rules for that attribute will be returned.
 ];

 $multipleSomeRules = User::getValidationRules('name', 'age'); // will return array of rules for specified attributes.

 // You can also call it with array as first parameter:
 $multipleSomeRules2 = User::getValidationRules(['name', 'age']);

不要害怕编写一些代码来生成您的自定义控制器特定规则。使用array_merge 和其他助手,实现你自己的(例如,一个助手将'required' 值添加到数组中,如果它不存在或删除它等)。不过,我强烈建议您使用 FormRequest 类来封装该逻辑。

【讨论】:

    【解决方案2】:

    你可以尝试使用laravel的验证laravel documentation

    它真的很容易使用和维护,只需按照以下步骤操作:

    运行工匠命令:php artisan make:request StoreYourModelName 这将在App/Http/Requests中创建一个文件

    在授权函数中将其设置为:

    public function authorize()
    {
       return true;
    }
    

    然后在规则函数中编写您的验证逻辑:

    public function rules()
    {
        return [
            'title' => 'required|unique:posts|max:255',
            'body' => 'required',
        ];
    }
    

    自定义错误消息在您的规则函数下方添加:

    public function messages()
    {
        return [
            'title.required' => 'A title is required',
            'body.required'  => 'A message is required',
        ];
    }
    

    最后要在你的控制器中使用它,只需将它作为参数添加到你的函数中。

    public function create(Request $request, StoreYourModelName $storeYourModelName)
    {
      //
    }
    

    这就是您需要做的所有事情,如果验证通过,它将在表单提交时进行验证,它将进入您的控制器,请记住,您的验证逻辑不必像我想的那样,我会向您展示一种可能的方式完成..

    【讨论】:

    • @Pouneh 只需要 4 步,剩下的由你决定,运行 artisan 命令 -> 设置授权返回 true -> 将验证逻辑添加到规则函数 -> 作为参数添加到控制器,记得添加控制器顶部的 using 语句。
    • 那么当您还必须在更新方法中进行验证时呢?然后你有一个 StoreModelRequest 和一个 UpdateModelRequest。
    • @commadelimited 您可以使用相同的验证类并根据表单方法更新您的逻辑,即如果发布则执行此验证规则,否则如果使用不同的验证规则。
    猜你喜欢
    • 2021-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-18
    • 2020-11-02
    • 1970-01-01
    • 2016-08-17
    相关资源
    最近更新 更多