
本文介绍如何从嵌套 json 解析后的多维关联数组中,批量提取所有层级下统一键名(如 nombre_ubigeo)对应的值,并提供健壮、可复用的实现方案。
本文介绍如何从嵌套 json 解析后的多维关联数组中,批量提取所有层级下统一键名(如 nombre_ubigeo)对应的值,并提供健壮、可复用的实现方案。
在处理类似 Peru Ubigeos 这类结构化地理数据时,原始 JSON 是一个「以省/大区 ID 为键、对应多个二级行政区(如省份)数组为值」的深层嵌套结构。目标是提取全部 nombre_ubigeo 字段(共 194 条),而非手动遍历或硬编码层级。
✅ 正确做法:递归 + array_map() 提取
首先需确保 json_decode() 使用 true 参数返回关联数组(而非 stdClass 对象),便于键名访问:
$provincias = json_decode(
file_get_contents("https://www.php.cn/link/27802e14b7689cc7d57176ffea7f37b5"),
true
);
接着,使用标准 foreach 遍历外层数组(每个键代表一个大区 ID),对每个子数组(即该大区下的所有省份)应用 array_map() 提取 nombre_ubigeo:
$nombreUbigeos = [];
foreach ($provincias as $provinciasList) {
// $provinciasList 是一个包含多个省份数组的数组(如 "2534" => [...])
$nombres = array_map(fn($item) => $item['nombre_ubigeo'] ?? null, $provinciasList);
$nombreUbigeos = array_merge($nombreUbigeos, $nombres);
}
// 过滤掉可能因缺失字段产生的 null 值(增强健壮性)
$nombreUbigeos = array_filter($nombreUbigeos, 'is_string');
$nombreUbigeos = array_values($nombreUbigeos); // 重置索引
echo "共提取 " . count($nombreUbigeos) . " 个 nombre_ubigeo:\n";
print_r($nombreUbigeos);
⚠️ 注意:原答案中 current($provincias) 是严重错误——它始终取第一个大区的数据,导致重复提取同一组省份,最终结果远少于 194 条。正确逻辑应是对 每个 $provinciasList(即每个大区的省份数组)单独映射。
? 替代方案:一行式 array_column()(推荐)
PHP 5.6+ 支持对多维数组直接使用 array_column() 提取列,但需配合 array_merge(...$arrays) 展平:
$nombreUbigeos = [];
foreach ($provincias as $provinciasList) {
$nombreUbigeos = array_merge($nombreUbigeos, array_column($provinciasList, 'nombre_ubigeo'));
}
$nombreUbigeos = array_values(array_filter($nombreUbigeos)); // 清洗 & 重索引
此方式更简洁、性能更优,且语义清晰。
?️ 安全与健壮性建议
- 空值防护:使用 ?? null 或 array_key_exists('nombre_ubigeo', $item) 避免 Undefined index 警告;
- 网络容错:生产环境务必添加 file_get_contents() 的错误检查(如 false === $json)及异常捕获;
- 缓存优化:频繁调用时建议本地缓存 JSON 文件,避免每次请求远程资源;
- 内存考量:若数据量极大,可考虑流式解析(如 json streaming parser),但本例 194 条完全适用内存加载。
最终,你将获得一个纯净、索引连续的字符串数组,例如:
[ 0 => 'Bagua', 1 => 'Bongara', 2 => 'Chachapoyas', // ... 共 194 项 ]
该方案简洁、可读、可维护,适用于任意深度相似结构的键值批量提取场景。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











