能否在Eloquent集合自定义属性上使用map、filter方法?遇Trying to get property of non-object错误
嘿,我之前也碰到过这个问题,咱一步步拆解解决它!
解决Laravel Eloquent集合自定义属性使用map/filter时的「Trying to get property of non-object」错误
先搞懂为啥会报错
这个错误大概率是两个原因导致的:要么你的集合里混进了非模型对象(比如null、纯数组/字符串,不是完整的Eloquent模型实例),要么你的自定义属性(比如访问器)定义得有问题,导致集合迭代时无法正确解析属性。
最常见的坑就是用pluck()或者select()只取部分字段,返回的集合元素不是完整模型实例,这时候访问模型的自定义属性肯定会炸。
可行的解决方案
1. 确保集合里全是完整的模型实例
如果你的查询是这样的:
// 只取部分字段,返回的是模型实例但字段不全,或者用pluck直接返回纯值集合 $users = User::select('id', 'name')->get(); $userNames = User::pluck('name');
纯值集合(比如pluck返回的)肯定不能访问模型的自定义属性。所以要保证你操作的是完整的Eloquent模型实例集合,用get()或者all()获取全量模型就没问题。
2. 正确定义自定义属性(访问器)
如果是用访问器定义的自定义属性,一定要把它加入模型的$appends数组,这样属性会自动加载到模型的数组/JSON表示中,集合操作时也能正常访问:
class User extends Model { protected $appends = ['full_name']; // 把访问器属性加入自动加载列表 public function getFullNameAttribute() { return $this->first_name . ' ' . $this->last_name; } }
之后不管是单个模型还是集合里的模型,$user->full_name都能正常访问,用map操作也不会报错:
$users->map(function($user) { return $user->full_name; });
3. 先过滤掉集合里的非模型对象
如果你的集合里可能混进null或者非模型实例,先做一层过滤:
// 只保留User模型实例 $filteredUsers = $users->filter(function($item) { return $item instanceof User; }); // 再进行后续的map/filter操作 $userFullNames = $filteredUsers->map(fn($user) => $user->full_name);
4. 用optional()处理关联属性的空值
如果是在访问关联模型的自定义属性时报错(比如关联不存在返回null),可以用Laravel的optional()函数兜底:
$users->map(function($user) { // 如果profile关联不存在,返回null而不是报错 return optional($user->profile)->display_name; });
5. 用transform()替代map(修改原集合场景)
如果需要直接修改原集合的元素,transform()会更贴合需求,而且能自动处理集合元素的异常情况:
$users->transform(function($user) { if ($user instanceof User) { return $user->full_name; } return '未知用户'; // 或者其他默认值 });
完整的正确示例
假设我们有User模型,定义了full_name访问器,然后正确操作集合:
// User模型定义 class User extends Model { protected $fillable = ['first_name', 'last_name']; protected $appends = ['full_name']; public function getFullNameAttribute() { return trim($this->first_name . ' ' . $this->last_name); } } // 控制器中的集合操作 $users = User::all(); // 获取完整的模型实例集合 // 用map获取所有用户的全名 $fullNames = $users->map(fn($user) => $user->full_name);
这样操作就不会再出现「Trying to get property of non-object」的错误啦!
内容的提问来源于stack exchange,提问作者Pavol Martis
相关产品推荐
相关产品推荐

