
本文详解如何使用 json_decode() 安全、准确地解析多层嵌套的 json 响应,并提取如 transaction_reference 和 status 等深层字段,避免因路径错误或数组索引误用导致的空值或致命错误。
本文详解如何使用 json_decode() 安全、准确地解析多层嵌套的 json 响应,并提取如 transaction_reference 和 status 等深层字段,避免因路径错误或数组索引误用导致的空值或致命错误。
在 PHP 中处理嵌套 JSON 时,关键在于严格遵循 JSON 的层级结构,并区分对象(stdClass)与数组(array)。原始 JSON 中 transfer_batches 和 disbursements 均为索引数组(即使只含一个元素),因此必须用方括号语法 [$index] 访问,而不能用对象箭头 ->0(该写法在 PHP 中非法,会导致语法错误)。
✅ 正确做法:先调用 json_decode($json, false)(默认返回对象)或 json_decode($json, true)(返回关联数组),再按结构逐级访问。推荐启用错误检查以提升健壮性:
<?php $response = '{
"data": {
"id": "1cc58ad2-ccfd-4ede-a6a6-35809c81cb8a",
"type": "payment",
"attributes": {
"status": "Sent",
"created_at": "2022-05-02T08:57:50.171+03:00",
"amount": { "currency": "KES", "value": "500.0" },
"transfer_batches": [{
"status": "Sent",
"amount": "500.0",
"disbursements": [{
"amount": "500.0",
"status": "Transferred",
"origination_time": "2022-05-02T08:57:50.171+03:00",
"transaction_reference": "1651471070",
"destination_type": "till",
"destination_reference": "3eccf0c1-ab6b-41a4-b51a-4e8f588105f1"
}]
}],
"metadata": { "something": "TST-01" },
"_links": { "callback_url": "http://portal.zarafu.com/payments" }
}
}
}';
// 1. 解码并验证 JSON 有效性
$jsonData = json_decode($response);
if (json_last_error() !== JSON_ERROR_NONE) {
throw new RuntimeException('Invalid JSON: ' . json_last_error_msg());
}
// 2. 安全提取顶层 status(位于 attributes 下)
$paymentStatus = $jsonData->data->attributes->status ?? 'Unknown';
// 3. 提取 transaction_reference —— 注意:transfer_batches 和 disbursements 是数组!
$transactionRef = 'N/A';
if (isset($jsonData->data->attributes->transfer_batches[0]->disbursements[0]->transaction_reference)) {
$transactionRef = $jsonData->data->attributes->transfer_batches[0]->disbursements[0]->transaction_reference;
}
echo "Payment Status: {$paymentStatus}\n";
echo "Transaction Reference: {$transactionRef}\n";
// 输出:
// Payment Status: Sent
// Transaction Reference: 1651471070
⚠️ 重要注意事项:
- ❌ 错误写法:$jsonData->data->attributes->transfer_batches->0->...(PHP 不支持数字属性名的箭头访问);
- ✅ 正确写法:$jsonData->data->attributes->transfer_batches[0]->disbursements[0]->transaction_reference;
- 始终使用 isset() 或空合并运算符 ?? 防御性访问,避免 Notice: Trying to get property 'xxx' of non-object;
- 若需遍历多个 disbursements,请用 foreach;若不确定结构深度,可结合 is_object() / is_array() 动态判断;
- 生产环境建议统一使用 json_decode($json, true) 返回关联数组,配合 array_key_exists() 和 [] 访问,语义更清晰且避免对象属性限制。
掌握层级映射与防御性访问,即可从容应对任意深度的嵌套 JSON。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











