Laravel网球场预订系统DateTime查询仅按日期筛选不识别时间怎么解决
问题根源
时间过滤失效核心有2个原因:
- Tournament模型未将
end_date字段声明为日期类型,字段值在PHP层面比较时被当成普通字符串处理,仅匹配了日期部分,忽略了时间维度 - 先执行
Tournament::all()再做集合过滤的写法,是把所有数据拉到PHP内存后再筛选,不仅性能差,也会因为类型不一致导致时间比较失效,应该直接在数据库层面做SQL条件过滤
修复步骤
1. 调整Tournament模型,声明end_date为日期类型
Laravel会自动将声明的字段转为Carbon日期实例,保证时间比较的精度:
class Tournament extends Model { use SoftDeletes; protected $table = 'tournaments'; // 新增以下配置,Laravel 7及以上版本推荐用$casts protected $casts = [ 'end_date' => 'datetime', ]; // 低版本Laravel可以用$dates属性,和上面$casts二选一即可 // protected $dates = ['end_date']; }
2. 重写ReserveController的过滤逻辑,改用查询构造器在数据库层面过滤
数据库会直接对datetime类型的end_date和用户提交的完整时间做比较,自动匹配时间维度,同时查询性能会大幅提升:
public function getLaneByDate(Request $request) { // 先做输入合法性校验 $request->validate([ 'date' => 'required|date', ]); // 直接在SQL层面做时间条件过滤,完整匹配日期+时间 $tournaments = Tournament::where('end_date', '<=', $request->input('date'))->get(); return view('/reserve-date', compact('tournaments')); }
修改完成后测试:用户输入11/30/2021 11:00时,会正确过滤掉end_date为NOV 30 2021 12:00的场地,仅返回结束时间小于等于查询时间的场地。
内容的提问来源于stack exchange,提问作者BigBongo
相关产品推荐
相关产品推荐

