
本文详解 laravel 项目中因误将 api 返回的关联数组当作对象访问而导致 “trying to get property 'name' of non-object” 错误的原因与修复方法,重点说明数据结构判断、安全取值及批量插入实践。
在使用第三方 API(如 RAWG)获取游戏数据时,开发者常假设响应体是对象(Object),从而直接使用 -> 操作符访问属性,例如 $result->name。但实际返回的数据结构通常是 关联数组(Associative Array),尤其当 API 使用 JSON 格式且 Laravel 的 HTTP 客户端(或封装库如 \Rawg)默认解析为数组时——此时若强行用对象语法访问,PHP 就会抛出 Trying to get property 'name' of non-object 错误。
以你提供的代码为例:
$response = \Rawg::load('games')->setParams([...])->get();
// 此处 $response 实际结构类似:['count' => 123, 'results' => [...]]
// 而非一个可遍历的对象集合$response 并非一个 Collection 或对象数组,而是一个包含 'results' 键的顶层数组。因此,正确入口应为 $response['results'],且每个 $result 是关联数组,需用方括号语法访问字段:
✅ 正确写法:
foreach ($response['results'] as $result) {
Games::insert([
'name' => $result['name'] ?? 'Unknown',
'ratings' => $result['ratings'][0]['title'] ?? null,
'platforms' => $result['platforms'][0]['platform']['name'] ?? null,
]);
}⚠️ 关键注意事项:
- 始终验证数据结构:可通过 dd($response) 或 var_dump(gettype($response)) 确认是 array 还是 object;
- 避免未定义索引错误:API 响应可能缺失某些字段(如空 ratings 数组),建议配合空合并运算符 ?? 或 optional() 辅助安全取值;
- 批量插入性能优化:Games::insert() 高效,但需确保所有字段类型与数据库列严格匹配(如 platforms 若为多平台,建议存为 JSON 字段并使用 ->json() 类型迁移);
- 扩展性建议:对嵌套结构(如 platforms 多维数组),推荐先规范化处理,例如提取主平台名或序列化为 JSON 字符串,而非硬编码 [0]。
总结:该错误本质是 PHP 类型误判所致。牢记“API JSON → 默认解析为 array”,坚持用 is_array() 初步校验、用 ?? 防御性编程、用 dd() 快速调试,即可彻底规避此类问题。










