You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:40:35