Laravel报Creating default object from empty value错误如何解决
错误产生原因
你触发的ErrorException: Creating default object from empty value错误,本质是PHP不允许直接对空值(null)以对象方式赋值属性。对应到你定位到的$agent->is_in_case = true;这行,前置查询$agent = Agent::find(auth()->user()->id_user);没有在agents表匹配到对应ID的记录,返回了null,你直接对null赋值对象属性就触发了报错。
除了这个直接触发报错的点,你的代码里还有多处同类风险和逻辑bug,不修复后续会陆续触发其他错误。
现存风险点梳理
- 核心报错点:
Agent::find()结果未做非空判断,查询不到记录时返回null,触发属性赋值错误 - 隐藏空值风险:开头
Cases::find($id_case)未做非空判断,后续调用$case->id_customer时如果案件不存在会触发同类错误 - 逻辑失效bug:判断坐席是否已接单时用了
->get()取结果,该方法永远返回集合实例(哪怕无匹配记录也是空集合),空集合在if判断中为真值,会导致不管坐席有没有接过单,都直接返回"Agent has accepted the request",后续接单逻辑完全无法执行 - 语法风险:直接取
$id_case[0]时没有判断$id_case是否为空,传入空值时会触发字符串偏移量非法错误 - 变量覆盖bug:先查询了Agent模型实例赋值给$agent,后续创建AgentInCase记录时又把结果覆盖赋值给$agent,最后给通知方法传参时传错了模型对象
修复后可直接运行的代码
public function accept(Request $request) { $id_case = $request->id_case; // 校验案件是否存在 $case = Cases::find($id_case); if (!$case) { return $this->sendError('参数错误', 400, '传入的案件ID不存在'); } // 校验当前登录账号是否为有效坐席 $agent = Agent::find(auth()->user()->id_user); if (!$agent) { return $this->sendError('权限不足', 403, '当前账号无接单权限'); } $maxAgent = 0; // 非空判断后再取案件ID首字符匹配最大接单数 if (!empty($id_case)) { switch ($id_case[0]) { case 'A': $maxAgent = 1; break; case 'B': $maxAgent = 3; break; case 'C': $maxAgent = 5; break; default: break; } } // 修复已接单判断逻辑:直接用数据库exists判断,性能更高也不会出现类型判断错误 $hasAccepted = AgentInCase::where('id_case', $id_case) ->where('id_agent', auth()->user()->id_user) ->exists(); if ($hasAccepted) { $message = 'Agent has accepted the request'; return $this->sendResponse([], $message, 200); } // 统计当前案件已接单数,直接用count聚合查询,减少内存占用 $currentAgentCount = AgentInCase::where('id_case', $id_case)->count(); if ($currentAgentCount < $maxAgent) { // 提前做过非空校验,此处不会再触发空对象赋值错误 $agent->is_in_case = true; $agent->save(); // 区分变量名,避免覆盖之前的Agent模型实例 $agentInCase = AgentInCase::create([ 'id_case' => $id_case, 'id_agent' => auth()->user()->id_user ]); // 发送FCM通知给客户 $message = [ 'title' => 'accept_agent', 'body' => 'New Agent Come To Help ', 'payment' => 'Rp 15.000' ]; // 提前做过案件非空校验,此处调用id_customer不会报错 $this->sendNotificationFirebase('customer', $case->id_customer, $message, $agentInCase); $message = 'Successfully accepted request'; return $this->sendResponse($case, $message, 200); } $message = 'Failed to accept request'; $errors = 'Case has been handled by another agent'; return $this->sendError($message, 400, $errors); }
关键修复逻辑说明
- 所有模型
find()查询后立刻做非空判断,从根源上杜绝对null值操作对象属性的问题,这也是解决你本次报错的核心 - 把判断存在性的
->get()替换为->exists(),统计数量的->get()替换为->count(),既修复了原有的逻辑判断bug,也提升了查询性能 - 区分不同模型的变量名,避免变量覆盖导致的传参错误
- 增加参数合法性前置判断,把异常拦截在逻辑执行早期,避免后续流程执行无意义的代码
内容的提问来源于stack exchange,提问作者ayshintao
相关产品推荐
相关产品推荐

