Laravel验证–日期格式月/月不接受特定值

时间:2019-01-31 18:55:47

标签: php laravel validation date laravel-5.4

对于付款方式的基本身份验证,我有以下验证规则(高级内容,例如CVD验证,现有卡等,之后将由Moneris处理)。

$rules = [
    "type" => "required|in:visa,mastercard",
    "nickname" => "required",
    "credit_card_number" => "required|numeric|digits:16",
    "expiry" => "required|string|size:5|date_format:m/y|after:today",
    "cvd" => "required|numeric|digits:3"
];

规则expiry不接受特定值04/yy,但接受03/yy05/yy;我不知道为什么会这样,但是我需要补救。有人遇到过这种行为吗?

作为参考,我通过dd($request->input(), $validator->passes(), $validator->errors());时的结果04/19如下:

array:6 [▼
  "type" => "visa"
  "nickname" => "Testing"
  "credit_card_number" => "4242424242424242"
  "expiry" => "04/19"
  "cvd" => "123"
  "masked_pan" => "************4242"
]
false
MessageBag {#502 ▼
  #messages: array:1 [▼
    "expiry" => array:1 [▼
      0 => "The expiry does not match the format m/y."
    ]
  ]
  #format: ":message"
}

当我发送05/19时,一切正常:

array:6 [▼
  "type" => "visa"
  "nickname" => "Testing"
  "credit_card_number" => "4242424242424242"
  "expiry" => "05/19"
  "cvd" => "123"
  "masked_pan" => "************4242"
]
true
MessageBag {#502 ▼
  #messages: []
  #format: ":message"
}

1 个答案:

答案 0 :(得分:0)

在Laravel 5.4中,此验证规则的工作方式似乎是一个问题。要解决此问题,我检查了01/前面的输入的日期有效性,如果有效,请将其合并到请求中,并用endOfMonth()处理after:today验证:

$mergeDate = null;
$rawInput = $request->input("expiry");
try {
    $mergeDate = Carbon::createFromFormat("d/m/y", "01/".$request->input("expiry"))->endOfMonth();  
} catch(\Exception $ex){}

$request->merge([
    "masked_pan" => str_repeat("*", 12).substr($request->input("credit_card_number", ""), -4),
    "expiry" => $mergeDate ? $mergeDate->format("d/m/y") : $request->input("expiry")
]);

现在,如果我通过04/22,它将检查01/04/22是否有效,然后转换为月末30/04/22,然后将其替换为传递给验证的值(还需要更新)

"expiry" => "required|string|size:8|date_format:d/m/y|after:today",

我还必须更新并传递$messages以避免给用户造成混乱:

$messages = [
    "expiry.size" => "The :attribute filed must be 5 characters.",
    "expiry.date_format" => "The :attribute field does not match the format m/y"
];

$validator = \Validator::make($request->all(), $rules, $messages);

最后,如果出现错误(因此用户看不到他们未输入的值),请用原始输入替换该值

if(!$validator->passes()){
    $request->merge(["expiry" => $rawInput]);
    return back()->withErrors($validator)->withInput();
}

一堆废话,但似乎可以处理04/22和其他日期。