You need to enable JavaScript to run this app. PHP多维数组如何保留原有键 仅对数字键项用array_values()解决json_encode问题
优惠活动
大模型
产品
解决方案
定价
更多

PHP多维数组如何保留原有键 仅对数字键项用array_values()解决json_encode问题

解决方案

核心问题说明

PHP 内置 json_encode() 的编码规则会直接决定输出格式:

  • 只有当数组的所有键为整数,且是从0开始连续递增的序列时,才会被编码为标准JSON数组格式 []
  • 只要数组存在非整数键,或是整数键不连续(比如从1开始、存在索引间隔),就会被强制编码为JSON对象格式 {}

你遇到的 supply 子数组使用非连续的数字键 1 作为索引,正是触发了上述规则,导致最终JSON输出不符合预期;而直接对全量数组调用 array_values() 会把顶层所有字符串键(比如 @context、@type)替换为数字索引,彻底破坏原有语义结构。

实现思路

采用递归遍历的方式逐层处理嵌套数组,匹配你的核心需求:

  • 逐层级判断数组属性:如果当前层是纯数字键构成的数组,就对这层调用 array_values(),重排为从0开始的连续索引
  • 如果当前层是字符串键构成的关联数组,完整保留原有键值对结构,不做任何键替换
  • 无论处理到哪一层,都会继续深入遍历节点下的数组类型值,重复上述判断流程,直到覆盖所有嵌套层级

可直接使用的工具函数

/**
 * 递归规范数字索引数组,保留字符串键关联结构
 */
function formatNestedArray(array $array): array
{
    // 判断当前层级是否为纯数字键数组
    $allNumericKeys = true;
    foreach (array_keys($array) as $key) {
        if (!is_int($key) && !ctype_digit((string)$key)) {
            $allNumericKeys = false;
            break;
        }
    }

    // 对纯数字键的层级重排连续索引
    if ($allNumericKeys) {
        $array = array_values($array);
    }

    // 递归处理所有子数组节点
    foreach ($array as $key => $value) {
        if (is_array($value)) {
            $array[$key] = formatNestedArray($value);
        }
    }

    return $array;
}

针对你提供的数组结构的执行效果

  • 顶层数组全为字符串键(@context、@type、name、supply、step),会被100%保留原有键名,不会出现全局调用array_values()导致的键值替换问题
  • 进入 supply 对应的子数组,检测到其为纯数字键结构,会自动调用array_values()把索引从1重排为0,满足json_encode()输出标准数组的要求
  • 进入 step 对应的子数组,检测到其为纯数字键结构,重排后依然保持从0开始的连续索引,不产生结构变化
  • 所有嵌套在字符串键下的子数组(比如HowToSupply、HowToStep、ImageObject节点),因为全是字符串键结构,会被完整保留原有语义,不会被修改。

轻量替代方案

如果数组嵌套层级较浅,不需要写通用递归函数,也可以手动对存在非连续数字键的节点单独处理:

  • 不修改顶层数组的字符串键
  • 仅对存在非连续数字键的supply节点单独调用array_values()
  • 处理完成后直接调用json_encode()即可输出符合预期的格式,避免递归带来的额外性能开销。

内容的提问来源于stack exchange,提问作者ralphjsmit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.27 08:15:09