【问题标题】:How to filter request data by keys from in validation rules?如何通过验证规则中的键过滤请求数据?
【发布时间】:2017-05-26 13:03:39
【问题描述】:

我正在编写一个多步骤注册表单。第一步,我需要收集first_namelast_namedob,然后创建一个Customer对象只有这三个字段

// RegistrationController.php
public function store_profile(Request $request) {
    $rules = ['first_name' => '...', 'last_name' => '...', 'dob' => '...'];
    $this->validate($request, $rules);

    Customer::create($request);
}

问题是其他字段,例如addresscitystate也可以填写

// Customer.php
protected $fillable = ['first_name', 'last_name', 'dob', 'address', 'city', 'state', ...];

我打算在注册的第二步(在public function store_address())中收集它们,但没有什么可以阻止用户POST将这些附加字段添加到第一步:

// RegistrationController.php
public function store_profile(Request $request) {
    $rules = ['first_name' => '...', 'last_name' => '...', 'dob' => '...'];
    $this->validate($request, $rules); // won't validate 'address', 'city', 'state'

    Customer::create($request); // will store everything that's fillable,
                                // no matter if it was validated or not...
}

因此,我的目标是通过在我的验证 $rules 变量中定义的数组键过滤 $request->all() 字段。这是我的尝试:

$data = [];
foreach(array_keys($rules) as $key) {
    $val = $request->{$key};
    if (! empty($val))
        $data[$key] = $val;
}
// in the end, $data will only contain the keys from $rules
// i.e. 'first_name', 'last_name', 'dob'

首先,是否有更有效/更简洁的方法来使用array_columnarray_intersect_key 或其他方法,可能无需手动循环?其次,有没有我不知道的更像 Laravel 的方法?

【问题讨论】:

    标签: php laravel validation laravel-5.3


    【解决方案1】:

    only()(和except())呢?

    Customer::create($request->only(['first_name', 'last_name', 'dob']));

    Customer::create($request->only(array_keys($rules)));

    编辑:在 Laravel 5.5 中,有 another solution:

    $rules = ['first_name' => '...', 'last_name' => '...', 'dob' => '...'];
    $data = $this->validate($request, $rules);
    
    Customer::create($data); // $data contains only first_name, last_name and dob
    

    【讨论】:

    • only() 可能有问题。如果你传递了['first_name', 'last_name', 'dob'],而$request 由于某种原因没有first_name,Laravel 会在请求中包含'first_name' => null。这可能会引发 SQL 异常“无默认值”,因为它会尝试插入 NULL
    • 是的,但是如果您通过$request->input('first_name') 获得输入,您也会获得NULL。在这里,您可以定义一个默认值 ($request->input('first_name', 'John Doe'))。但我宁愿在模型的public setFirstNameAttribute($value) 方法中处理这个问题。
    • 我解决这个问题的一种方法是在我的array_keys($rules)array_keys($request->all()) 上使用array_intersect 获取$keys。然后,我打电话给Customer::create($request->only($keys)),这似乎是安全的,但很笨拙且不明显。你认为有更好的方法吗?
    • @Alex 也许像array_filter($request->only([...]), 'isset')?见php.net/manual/en/function.array-filter.php
    【解决方案2】:

    如果我是你,我会这样做:

    public function store_profile(Request $request) {
        $rules = ['first_name' => '...', 'last_name' => '...', 'dob' => '...'];
        $this->validate($request, $rules); // won't validate 'address', 'city', 'state'
    
        Customer::create([
            'first_name' => $request->input('first_name');
            'last_name'  => $request->input('last_name');
            'dob'        => $request->input('dob');
        ]); 
    
    }
    

    甚至更简单:

    Customer::create($request->only(['first_name', 'last_name', 'dob']));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-03-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-21
      • 1970-01-01
      • 2016-06-24
      • 1970-01-01
      相关资源
      最近更新 更多