Laravel关联过滤时报Trying to get property of non-object错误排查
解决Laravel关联过滤后出现Trying to get property of non-object错误
这个问题我之前也碰到过,其实根源很容易理清:当你给adminProfile关联加上where('status', 1)的过滤条件后,那些没有符合条件的adminProfile记录的User模型,它们的adminProfile属性会变成null,而不是一个空的模型对象。这时候直接访问$user->adminProfile->company_name,自然就会触发“尝试获取非对象的属性”错误。
下面给你几个实用的解决方法,你可以根据自己的业务场景选择:
方法1:使用可选属性访问符(最快捷)
从PHP 7.4+和Laravel 8+开始,支持使用?->可选操作符来安全访问属性,它会自动判断前面的对象是否为null,如果是就直接返回null,不会报错。
在模板里改成这样:
{{ $user->adminProfile?->company_name }}
如果想给个默认值,还可以结合null合并操作符:
{{ $user->adminProfile?->company_name ?? '暂无公司名称' }}
方法2:给关联设置默认模型
如果希望即使没有符合条件的关联记录,adminProfile也始终是一个模型实例(而不是null),可以在User模型的关联定义里加上withDefault():
// User模型中的adminProfile关联方法 public function adminProfile() { // 可以空着,也可以设置默认属性值 return $this->hasOne(AdminProfile::class)->withDefault([ 'company_name' => '默认公司名称' ]); }
这样不管关联过滤后有没有匹配的记录,$user->adminProfile都会是一个AdminProfile对象,访问company_name就不会报错了。
方法3:只查询有有效关联的用户
如果你的业务场景只需要那些拥有status=1的adminProfile的管理员用户,那可以用whereHas来过滤掉没有符合条件关联的用户,同时结合with预加载:
$users = User::role('admin') ->whereHas('adminProfile', function($q) { $q->where('status', 1); }) ->with('adminProfile') ->get();
这样查询出来的所有User模型,它们的adminProfile都一定是存在且符合条件的对象,自然不会出现报错的情况。
内容的提问来源于stack exchange,提问作者Ahsan
相关产品推荐
相关产品推荐

