
使用 array_merge() 会重置数字键导致 JSON 输出为数组,而通过数组加法(+)运算符或 JSON_FORCE_OBJECT 标志,可确保键名保留并输出标准关联对象格式。
使用 `array_merge()` 会重置数字键导致 json 输出为数组,而通过数组加法(`+`)运算符或 `json_force_object` 标志,可确保键名保留并输出标准关联对象格式。
在 PHP 中,将多个数组合并为一个保持原始键名(尤其是字符串或非连续数字键)的关联结构,并最终通过 json_encode() 输出为 JSON 对象(而非索引数组),是常见但易出错的操作。核心问题在于:array_merge() 会对纯数字键(numeric keys)进行重新索引,即使键是字符串形式(如 "1"、"2"),只要其值可被解释为整数,PHP 在内部仍可能将其视为数字键,从而触发重排逻辑。
✅ 正确做法一:使用数组加法运算符 +
该操作符执行“左侧优先”的键合并——保留左数组的键值对,仅将右数组中左数组不存在的键加入结果,且完全不修改原始键类型与顺序:
<?php $array = ["1" => 1, "2" => 4];
$array1 = ["3" => 5];
$temp = $array + $array1;
print_r($temp);
// 输出:Array ( [1] => 1 [2] => 4 [3] => 5 )
echo json_encode($temp);
// 输出:{"1":1,"2":4,"3":5}
?>
⚠️ 注意:+ 运算符不覆盖左操作数已存在的键,若需覆盖或深度合并,请考虑 array_replace() 或自定义逻辑。
✅ 正确做法二:强制 JSON 输出为对象(兜底方案)
当数组结构复杂(如含混合键、动态生成、或无法控制键类型)时,可直接使用 JSON_FORCE_OBJECT 标志,强制 json_encode() 将任何数组序列化为 JSON 对象(即 {} 包裹),而非数组 []:
<?php $array = ["1" => 1, "2" => 4];
$array1 = ["3" => 5];
$temp = array_merge($array, $array1); // 此时仍可能被重索引
echo json_encode($temp, JSON_FORCE_OBJECT);
// 输出:{"0":1,"1":4,"2":5} ← 键名变为 0,1,2(因 array_merge 重索引)
// 但至少保证了 JSON 是对象格式,而非数组
// 更推荐:先用 + 合并,再加标志确保语义清晰
$temp = $array + $array1;
echo json_encode($temp, JSON_FORCE_OBJECT); // {"1":1,"2":4,"3":5}
?>
? 关键区别总结
| 方法 | 是否保留原始键 | 是否覆盖重复键 | JSON 输出类型 | 适用场景 |
|---|---|---|---|---|
| array_merge($a, $b) | ❌(数字键重索引) | ✅(右覆盖左) | 可能为 [] | 需要值覆盖且接受索引重排 |
| $a + $b | ✅(严格保留所有键) | ❌(左优先,不覆盖) | 自动为 {}(当键非连续整数) | 精确控制键映射,构建配置/映射表 |
| json_encode(..., JSON_FORCE_OBJECT) | ✅(不影响数组本身) | — | 强制 {} | 兜底保障 JSON 结构一致性 |
? 最佳实践建议
- 若目标是构造键值明确的配置、映射或 API 响应对象,优先使用 + 运算符;
- 避免依赖 array_merge() 处理含字符串键或非连续数字键的关联数组;
- 在调用 json_encode() 前,可用 is_array($arr) && array_keys($arr) !== range(0, count($arr)-1) 判断是否为“真正关联数组”,再决定是否启用 JSON_FORCE_OBJECT;
- 始终注意键的类型:$array[1] 和 $array["1"] 在 PHP 中等价,但 json_encode() 对键名的处理取决于数组内部结构,而非字面量写法。
通过合理选择合并策略与 JSON 编码选项,即可稳定输出符合预期的关联 JSON 对象。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











