Laravel中出现Attempt to read property 'episode' on null错误的排查求助
问题排查与解决方案
错误 Attempt to read property "episode" on null 本质是 $course 变量为null,导致后续调用 $course->episode 触发报错,核心问题出在关联模型命名、空值校验和时长计算逻辑上,具体修复步骤如下:
1. 修复Episode模型的关联方法
Eloquent的belongsTo对应单数关联关系,你的Episode模型里用了复数方法名courses(),会导致Eloquent自动推断错误的外键(比如找courses_id而非正确的course_id),最终$episode->course返回null。修改Episode.php:
// Episode.php public function course() { return $this->belongsTo(Course::class); }
2. 添加空值防御校验
即使修复了关联,也要做防御性编程,避免创建Episode时未传入有效course_id导致的空值问题:
// AdminController.php public function setCourseTime($episode) { // 先判断关联的课程是否存在 if (!$course = $episode->course) { return; // 也可根据业务需求抛出异常或记录日志 } // 预先加载关联,避免N+1查询 $course->load('episode'); $course->time = $this->getCourseTime($course->episode->pluck('time')); $course->save(); }
3. 优化时长计算逻辑
原getCourseTime方法用strtotime处理时长会导致错误(strtotime返回的是时间戳,而非时长秒数),改为直接解析时长累加:
protected function getCourseTime($times) { $totalSeconds = 0; foreach ($times as $row) { $parts = explode(':', $row); if (count($parts) === 2) { // 处理 mm:ss 格式 $totalSeconds += ($parts[0] * 60) + (int)$parts[1]; } elseif (count($parts) === 3) { // 处理 hh:mm:ss 格式 $totalSeconds += ($parts[0] * 3600) + ($parts[1] * 60) + (int)$parts[2]; } } // 把总秒数格式化为 H:i:s return gmdate('H:i:s', $totalSeconds); }
4. 确保请求参数合法性
在EpisodeRequest中添加course_id的校验规则,防止传入无效值:
// EpisodeRequest.php public function rules() { return [ 'course_id' => 'required|exists:courses,id', 'time' => 'required|regex:/^([0-9]{2}:){1,2}[0-9]{2}$/', // 校验时长格式 // 其他字段规则... ]; }
内容的提问来源于stack exchange,提问作者Raymond
相关产品推荐
相关产品推荐

