【问题标题】:Validating fields conditionally using Laravel使用 Laravel 有条件地验证字段
【发布时间】:2017-06-28 16:08:58
【问题描述】:

我对 Laravel 有以下验证规则:

return [
    'offer_type' => 'required|in:permanent,temporary',
    'start_date' => 'required_if:offer_type,temporary|date_format:d/m/Y',
    'end_date' => 'required_if:offer_type,temporary|date_format:d/m/Y|after:start_date',
];

基本上,如果offer_type 是temporary,则需要start_date 和end_date,并且必须遵循d/m/Y 格式。此外,end_date 必须在 start_date 之后。

如果offerType 是permanent,则无需验证start_date 或end_date,因为它们甚至没有被使用。

我遇到的问题是,如果用户发送如下数据:

  • offerType:永久
  • startDate: foo
  • endDate:酒吧

然后 Laravel 将引发验证错误,即使 start_date 和 end_date 不需要验证,因为报价类型是 permanent。

如果offer_type 是temporary,我怎样才能让Laravel 只验证start_date 和end_date。

我的(坏)解决方案

我发现解决此问题的唯一方法是执行以下操作:

将上面的验证规则改成如下:

return [
    'offer_type' => 'required|in:permanent,temporary',
    'start_date' => 'required_if:offer_type,temporary',
    'end_date' => 'required_if:offer_type,temporary',
];

并将以下代码添加到验证器:

$validator->after(function (Validator $validator) {
    $data = $validator->getData();
    $failed = $validator->failed();

    if (array_key_exists('offerType', $data) &&
        $data['offerType'] === 'temporary' &&
        array_key_exists('start_date', $data) &&
        array_key_exists('end_date', $data) &&
        !array_key_exists('start_date', $failed) &&
        !array_key_exists('end_date', $failed)
    ) {
        $startDateString = $data['start_date'];
        $endDateString = $data['end_date'];

        $startDate = Carbon::createFromFormat('d/m/Y', $startDateString);
        $endDate = Carbon::createFromFormat('d/m/Y', $endDateString);

        if ($startDate === false) {
            $validator->errors()->add('start_date', 'Start date must be in the format "dd/mm/yyyy"');
        }

        if ($endDate === false) {
            $validator->errors()->add('end_date', 'End date must be in the format "dd/mm/yyyy"');
        }

        if ($startDate !== false && $endDate !== false && $endDate->lt($startDate)) {
            $validator->errors()->add('end_date', 'End date must be after or equal to the start date');
        }
    }
});

【问题讨论】:

    标签: laravel laravel-5 laravel-5.2 laravel-5.1 laravel-validation


    【解决方案1】:

    我建议你有一个单独的 FormRequest 类。那么您的rules() 将如下所示:

    public function rules()
    {
        $rules = [
            'offer_type' => 'required|in:permanent,temporary',
            'start_date' => 'required_if:offer_type,temporary',
            'end_date' => 'required_if:offer_type,temporary',
        ];
    
        if ($this->offer_type == 'permament') {
            $this->getInputSource()->remove('start_date'); // optionally you may remove start_date from request
            $this->getInputSource()->remove('end_date');  // same of end_date
            unset($rules['start_date']); 
            unset($rules['end_date']);
        }
    
        return $rules;
    }
    

    Form Request Validation 上的 Laravel 文档

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-21
      • 1970-01-01
      • 1970-01-01
      • 2023-02-13
      • 1970-01-01
      相关资源
      最近更新 更多