Controller的多个验证器

时间:2018-01-25 13:04:23

标签: php laravel-5.5

我想为表单创建多个验证器,用于创建或编辑某些对象。 我有这种方法的User模型:

public function rules()
    {
        return [
            'name' => 'required|string|max:255',
            'email' => 'required|string|email|max:255|unique:users',
            'password' => 'required|string|min:6|confirmed',
        ];
    }

我有默认资源UserController

public function store(Request $request, User $user)
    {
        request()->validate($user->rules()); //this is nice according to mvc pattern (I hope it is)
        User::create([ 
            ...
        ]);
    }

public function update(Request $request, $id)
    {
        request()->validate([
            'name' => 'required|string|max:255',
            'email' => 'required|string|email|max:255|unique:users',
            'password' => 'required|string|min:6|confirmed',
        ]);
        User::find($id)->update($request->all());
        ...
    }
update()不同,

User方法没有store()实例作为参数。但我不想要任何过多的代码。我应该rules()静态并使用User::rules()吗?我知道测试静态方法非常困难,但实际上我并不知道这种方式的优缺点。有什么好的解决方案吗?

2 个答案:

答案 0 :(得分:0)

如果您使用相同的验证进行插入和更新,则更新时会出现问题,因为规则包含:

enter code here`'email' => 'required|string|email|max:255|unique:users'

这意味着更新将始终在'unique:users'验证失败,因为电子邮件已记录在数据库中。

我认为如果您愿意,静态功能也不错。编程风格很多,您可以选择自己的风格。决赛是相同的,让它发挥作用

根据你的条件,我更喜欢把它变成静态变量,而不是需要调用一个函数,因为规则只是一个字符串数组。但是你需要使用PHP7。

class User {
    static $RULES =  [
                'name' => 'required|string|max:255',
                'email' => 'required|string|email|max:255|unique:users',
                'password' => 'required|string|min:6|confirmed',
            ];
}

然后当需要更新规则时,我将进行自定义唯一验证,除了参数之外可以接受,例如:

$rules = User::$RULES; //Clone
$rules[email] .= " id!={$user->id}" // Append with space
// Email rule will like this
// required|string|email|max:255|unique:users id!=23

然后我需要修改唯一验证以支持该参数。这个例子来处理它:

function unique($str_to_validate, $rule)
{
    if( strpos($rule, ' ') !== false )
    {
        //Has except object notation
        list($rule, $condition) = explode(' ', $rule, 2);
        //Add where condition on DB query
        $this->db->where($condition);
    }

    // Your default validation here
    // ...
}

答案 1 :(得分:0)

我建议使用FormRequests来保持代码分离。

https://laravel.com/docs/5.5/validation#form-request-validation

它们允许您在控制器方法中验证您的请求,而不是在验证数据到达验证器之前增加验证数据。

另一个很大的好处是authorize()方法,您可以进一步微调谁可以访问路由方法以及如何访问。

您可以使用一组可以继承的通用规则定义BaseFormRequest类。

如果验证失败,它会自动将错误刷新到会话,或者如果请求是ajax,则返回JSON响应。