Laravel:将API响应转为Collection后在Blade打印报错排查
问题分析:Laravel Blade遍历Collection时报错"Attempt to read property 'first_name' on array"
操作步骤
我在Laravel项目中处理API响应数据,做了以下操作:
- 将API响应转为Collection:
$customers = collect(json_decode($response, true));
- 在Blade模板中遍历数据:
@foreach($customers as $row) <tr> <td>{{$row->first_name}} {{$row->last_name}}</td> <td>{{$row->email}}</td> <td>{{$row->phone}}</td> <td>{{$row->addresses['country_name']}}</td> </tr> @endforeach
报错信息
Attempt to read property "first_name" on array
实际Collection结构
Illuminate\Support\Collection {#341 ▼ // app\Http\Controllers\IntegrationController.php:61 #items: array:1 [▼ "customers" => array:3 [▼ 0 => array:27 [▼ "id" => 6895839936762 "email" => "russel.winfield@example.com" "accepts_marketing" => false "created_at" => "2023-10-20T11:06:26-04:00" "updated_at" => "2023-10-20T11:06:26-04:00" "first_name" => "Russell" "last_name" => "Winfield" "orders_count" => 0 "state" => "disabled" "total_spent" => "0.00" "last_order_id" => null "note" => "This customer is created with most available fields" "verified_email" => true "multipass_identifier" => null "tax_exempt" => false "tags" => "VIP" "last_order_name" => null "currency" => "USD" "phone" => "+16135550135" "addresses" => array:1 [▶] "accepts_marketing_updated_at" => "2023-10-20T11:06:26-04:00" "marketing_opt_in_level" => null "tax_exemptions" => [] "email_marketing_consent" => array:3 [▶] "sms_marketing_consent" => array:4 [▶] "admin_graphql_api_id" => "gid://shopify/Customer/6895839936762" "default_address" => array:17 [▶] ] 1 => array:26 [▶] 2 => array:26 [▶] ] ] #escapeWhenCastingToString: false }
问题原因
有两个核心错误:
- 遍历对象错误:当前
$customersCollection只包含一个键值对(键为customers,值是客户列表数组),直接遍历$customers会拿到整个客户列表数组,而非单个客户数据。 - 访问方式不匹配:
json_decode($response, true)会将JSON转为关联数组,不是对象,因此不能用->访问属性,必须用数组下标[]。
解决方案
方案一:保持数组格式访问
- 控制器中取出真实的客户列表:
// 先转数组,取出customers列表后再转Collection(或直接传数组) $customerList = collect(json_decode($response, true)['customers']);
- Blade中调整遍历和访问方式:
@foreach($customerList as $row) <tr> <td>{{$row['first_name']}} {{$row['last_name']}}</td> <td>{{$row['email']}}</td> <td>{{$row['phone']}}</td> <td>{{$row['addresses'][0]['country_name']}}</td> </tr> @endforeach
注:addresses是数组,需通过下标(如[0])获取具体地址后再取country_name。
方案二:转为对象格式访问
如果习惯用对象属性访问,去掉json_decode的第二个参数(默认转为对象):
- 控制器中处理数据:
$responseObj = json_decode($response); $customerList = collect($responseObj->customers);
- Blade中用对象语法访问:
@foreach($customerList as $row) <tr> <td>{{$row->first_name}} {{$row->last_name}}</td> <td>{{$row->email}}</td> <td>{{$row->phone}}</td> <td>{{$row->addresses[0]->country_name}}</td> </tr> @endforeach
内容的提问来源于stack exchange,提问作者Hola
相关产品推荐
相关产品推荐

