我们的应用需要将CSV文件导入数据库,其中包含日期字段。为此,我们编写了一个日期解析器:
class DateParser { public function parse(mixed $value): string { try { return Carbon::parse($value)->format('Y-m-d'); } catch (Exception $exception) { return $value; } } }
登录后复制
这段代码利用Laravel的Carbon库,简洁高效。然而,当用户输入仅包含月和日的数据(例如“11/11”)时,它会被解析为当前年份的日期(例如“2025-11-11”),这与预期不符。我们希望在这种情况下抛出异常并返回原始值。
最初,我们尝试使用正则表达式来验证日期格式,但发现要涵盖所有可能的格式非常复杂。 我们也考虑过利用ChatGPT生成的正则表达式:
$pattern = '/(?:(?:19|20)d{2}[-/.](?:0?[1-9]|1[0-2])[-/.](?:0?[1-9]|[12][0-9]|3[01]) # yyyy-mm-dd, yyyy/mm/dd, yyyy.mm.dd | (?:0?[1-9]|1[0-2])[-/.](?:0?[1-9]|[12][0-9]|3[01])[-/.](?:19|20)d{2} # mm-dd-yyyy, mm/dd/yyyy, mm.dd.yyyy | (?:0?[1-9]|[12][0-9]|3[01])[-/.](?:0?[1-9]|1[0-2])[-/.](?:19|20)d{2})/x';
登录后复制
但它不够完善,无法处理所有情况,例如”2020-12″这样的输入。
随后,我们尝试使用Laravel的验证器:
Validator::make([ 'date' => '11/11' ], [ 'date' => ['date'] ]);
登录后复制
验证器抛出错误,表明Laravel的日期验证机制能够正确处理这种情况。 深入研究Laravel的验证机制,我们发现它使用了PHP内置的date_parse()和checkdate()函数。
date_parse()函数返回一个数组,包含日期的各个组成部分。checkdate()函数则验证日期的有效性。 最终,我们采用以下解决方案:
public function parse(mixed $value): string { $date = date_parse($value); if (checkdate($date['month'], $date['day'], $date['year'])) { return Carbon::create($date['year'], $date['month'], $date['day'])->format('Y-m-d'); } return $value; }
登录后复制
这个解决方案利用了PHP内置函数的优势,简洁且可靠。
经验总结: 面对问题,我们倾向于快速编写自定义解决方案,例如使用正则表达式或复杂的逻辑。然而,这可能会导致维护困难、扩展性差以及潜在的错误。 在编写自定义代码之前,务必先探索框架或语言本身提供的功能,这通常能提供更可靠、更易维护的解决方案,并符合最佳实践。
以上就是以正确的方式解决问题:利用框架在快速修复的详细内容,更多请关注php中文网其它相关文章!