Laravel获取ID时触发Trying to get property of non-object错误排查求助
搞定「Trying to get property of non-object」错误:分析与修复
嘿,我帮你梳理下问题所在,以及对应的解决办法:
首先,先明确你的场景:你在做请假系统的权限逻辑,需要根据用户层级收集所有可查看的下属ID,但代码运行时触发了「Trying to get property of non-object」错误,这背后有两个核心问题:
1. 直接访问null对象的属性
这个错误的本质是:当你用Users::where('pic_for',$pic_for)->first()查询时,如果没有匹配到任何用户,它会返回null,而你直接去访问$query2->pic_for,就相当于从一个非对象(null)里拿属性,自然会报错。
举个例子,当循环到$pic_for=1时,数据库里没有用户的pic_for是1,$query2就变成了null,这时候执行if($query2->pic_for==null),直接触发错误。
2. 字段名不匹配(隐藏的大坑)
看你的数据库表结构,字段名是person_in_charge,但代码里全程用的是pic_for!这会导致你的查询根本找不到正确的数据,大概率会返回null,这也是触发错误的重要原因之一。
修复方案:调整逻辑+修正字段名
我建议用递归函数来处理层级结构(比while循环更清晰),同时每次查询后先判断结果是否存在,再访问属性:
修正后的代码
$id = '5'; $currentUser = Users::where('id', $id)->first(); $accessibleUserIds = []; // 当前用户是最高级(没有负责人),收集所有下属及下属的下属 if ($currentUser->person_in_charge === null) { // 获取直接下属 $directSubordinates = Users::where('person_in_charge', $id)->get(); foreach ($directSubordinates as $subordinate) { $accessibleUserIds[] = $subordinate->id; // 递归收集下属的所有下级 $this->collectAllSubordinates($subordinate->id, $accessibleUserIds); } dd($accessibleUserIds); } // 辅助函数:递归收集所有下属ID function collectAllSubordinates($parentId, &$idArray) { $subordinates = Users::where('person_in_charge', $parentId)->get(); foreach ($subordinates as $subordinate) { $idArray[] = $subordinate->id; // 继续向下收集 $this->collectAllSubordinates($subordinate->id, $idArray); } }
关键修复点
- 修正字段名:把代码里的
pic_for全部替换成数据库实际的字段名person_in_charge,确保查询能找到正确数据 - 判断对象是否存在:用
get()获取所有下属(而不是first(),避免漏掉多个同级下属),遍历处理时无需担心null,因为get()返回的是集合,即使为空也可以安全遍历 - 递归替代while循环:层级结构用递归逻辑更直观,也更容易维护,避免while循环中出现的死循环或null判断遗漏问题
如果还是想用while循环的话,也必须在每次获取$query2后先判断是否为null:
$id='5'; $query= Users::where('id',$id)->first(); $pic=array(); if($query->person_in_charge==null) { // 获取直接下属 $directSubs = Users::where('person_in_charge',$id)->get(); foreach($directSubs as $sub) { $pic[] = $sub->id; $pic_for = $sub->id; while(true) { $query2 = Users::where('person_in_charge',$pic_for)->first(); // 先判断$query2是否存在 if(!$query2) { break; } $pic[]=$query2->id; $pic_for = $query2->id; } } dd($pic); }
不过这种while循环的方式还是会漏掉同一个上级的多个下属(比如ID2的下属有ID1和ID3,用first()只能拿到其中一个),所以更推荐递归+get()的方案。
内容的提问来源于stack exchange,提问作者Ikram Shabri
相关产品推荐
相关产品推荐

