
本文详解 PHP 解析含嵌套 JSON 字符串的数组结构,特别是当 properties 字段本身是 JSON 格式字符串而非原生数组时,需二次 json_decode 才能安全访问如 firstname.value 等深层键值。
本文详解 php 解析含嵌套 json 字符串的数组结构,特别是当 `properties` 字段本身是 json 格式字符串而非原生数组时,需二次 `json_decode` 才能安全访问如 `firstname.value` 等深层键值。
在实际开发中(例如对接 HubSpot、Salesforce 或自定义 CRM 导出的 JSON 文件),常遇到一种“伪嵌套”结构:外层是标准 JSON,但某个字段(如 properties)的值并非对象或数组,而是被 JSON 编码过的字符串。此时直接使用 $data['contacts'][0]['properties']['firstname']['value'] 会触发 PHP 致命错误(Fatal error: Cannot use string as an array),因为 PHP 将其视为纯字符串,而非可遍历的关联数组。
✅ 正确解析步骤
-
首次解码:用
json_decode($json, true)将原始 JSON 文件转为 PHP 关联数组; -
识别字符串型属性字段:检查
$data['contacts'][0]['properties']的类型——若为string且内容以{或[开头,则大概率是 JSON 字符串; -
二次解码:对
properties字段单独调用json_decode(..., true),得到真正的属性数组; -
安全访问:再从中提取
firstname['value']、email['value']等字段。
? 完整示例代码
<?php $json = file_get_contents('./file.json'); // 注意文件扩展名应为 .json,非 .json(原文笔误)
// 第一次解码:获取顶层结构
$data = json_decode($json, true);
if (json_last_error() !== JSON_ERROR_NONE) {
throw new RuntimeException('Invalid JSON format in source file.');
}
// 检查 contacts 是否存在且非空
if (!isset($data['contacts']) || !is_array($data['contacts']) || empty($data['contacts'])) {
throw new RuntimeException('No contacts found or invalid contacts structure.');
}
// 取第一个联系人
$contact = $data['contacts'][0];
// 关键:properties 是 JSON 字符串,需二次解码
if (isset($contact['properties']) && is_string($contact['properties'])) {
$properties = json_decode($contact['properties'], true);
if (json_last_error() !== JSON_ERROR_NONE) {
throw new RuntimeException('Failed to decode properties JSON string.');
}
} else {
$properties = $contact['properties'] ?? [];
}
// 现在可安全访问字段(注意:value 值可能为 null 或不存在)
$firstname = $properties['firstname']['value'] ?? '';
$email = $properties['email']['value'] ?? '';
$phone = $properties['phone']['value'] ?? '';
echo "First Name: {$firstname}\n";
echo "Email: {$email}\n";
echo "Phone: {$phone}\n";
⚠️ 注意事项与最佳实践
-
始终校验 JSON 解码结果:使用
json_last_error()判断是否解析失败,避免静默错误; -
防御性访问:用空合并运算符
??或isset()检查深层键是否存在,防止Notice: Undefined index; -
区分数据类型:可通过
var_dump(gettype($contact['properties']))快速确认其是否为字符串; -
性能考虑:若 contacts 数量庞大,建议将
json_decode逻辑封装为函数并复用,避免重复解析; -
编码一致性:确保源 JSON 文件为 UTF-8 编码,必要时用
mb_convert_encoding()预处理。
掌握这种“双层 JSON 解析”模式,不仅能解决当前问题,还能从容应对 API 返回中混合原始数据与序列化字段的复杂场景。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











