Laravel直播预约提醒Job数据库查询无结果问题求助
排查直播提醒Job数据库查询无结果的问题
从你的代码来看,主要有几个关键问题导致数据库查询无法返回结果,我来逐个拆解:
1. 第一个查询的语法错误与SQL注入风险
你使用DB::raw()拼接SQL语句时,没有给LIKE后的日期字符串添加引号,这会导致SQL语法错误,数据库无法正确解析你的查询条件。而且直接拼接变量到SQL里存在严重的SQL注入风险。
错误代码片段:
$nextLivestreams = DB::raw('SELECT `id` from livestreams WHERE startAt LIKE '.$time.'%')->get();
正确做法是用Laravel查询构造器自动处理参数绑定和引号,避免手动拼接:
$nextLivestreams = DB::table('livestreams') ->select('id') ->where('startAt', 'LIKE', $time . '%') ->get();
2. 第二个查询未执行获取数据
在获取注册用户时,你只构建了查询构造器实例,但没有调用->get()方法执行查询,所以$registeredUsers并不是可遍历的数据集:
错误代码片段:
$registeredUsers = DB::table('event_registrations')->select('email')->where('livestream_id', $livestream);
需要补充->get()来触发数据库查询:
$registeredUsers = DB::table('event_registrations') ->select('email') ->where('livestream_id', $livestream->id) // 这里还要注意下面的取值问题 ->get();
3. 直播ID取值错误
遍历$nextLivestreams时,$livestream是一个数据库查询返回的对象,直接把它传给where('livestream_id', $livestream)会导致匹配错误,应该取对象的id属性:
where('livestream_id', $livestream->id)
4. 时间计算的潜在优化点
你用DateTime加24小时获取明天日期的逻辑没问题,但如果startAt是datetime类型,用日期范围查询会比LIKE更精准:
// 用Laravel自带的Carbon工具类更简洁 $tomorrowStart = now()->startOfDay()->addDay(); $tomorrowEnd = now()->endOfDay()->addDay(); $nextLivestreams = DB::table('livestreams') ->select('id') ->whereBetween('startAt', [$tomorrowStart, $tomorrowEnd]) ->get();
修正后的完整handle方法
public function handle() { // 获取明天的完整日期范围 $tomorrowStart = now()->startOfDay()->addDay(); $tomorrowEnd = now()->endOfDay()->addDay(); $nextLivestreams = DB::table('livestreams') ->select('id') ->whereBetween('startAt', [$tomorrowStart, $tomorrowEnd]) ->get(); foreach ($nextLivestreams as $livestream) { $registeredUsers = DB::table('event_registrations') ->select('email') ->where('livestream_id', $livestream->id) ->get(); foreach ($registeredUsers as $userEmail) { // 记得替换成用户的真实邮箱,不要用固定的'myemail' Mail::to($userEmail->email)->send(new EventReminderMail()); } } }
内容的提问来源于stack exchange,提问作者guilhermebueno6
相关产品推荐
相关产品推荐

