You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP中使用array_merge合并数组时子数组元素被覆盖的问题及优化实现方案咨询

解决PHP请求参数构建中Headers被覆盖的问题

你的问题出在array_merge()的行为上:当遇到同键名的数组元素时,它会直接用新数组替换旧数组,而不是把两个数组合并到一起。所以默认的Content-Type头才会被传入的X-Api-Token头覆盖掉。

快速修复方案

我们可以针对headers这种需要合并的数组类型选项,单独处理合并逻辑,其他选项保持正常覆盖。修改后的代码如下:

function buildOptions(array $options = []) {
    $supportedOptions = [
        'method' => 'POST',
        'payload' => [],
        'headers' => ['Content-Type: application/json'],
        'url' => 'https://example.com/api',
    ];

    $updatedOptions = $supportedOptions;
    foreach ($options as $key => $value) {
        // 只对headers做数组合并,其他键直接覆盖默认值
        if ($key === 'headers' && is_array($value)) {
            $updatedOptions[$key] = array_merge($updatedOptions[$key], $value);
        } else {
            $updatedOptions[$key] = $value;
        }
    }

    return $updatedOptions;
}

$payload = ['Collection' => 'Products'];
$input = [
    'headers' => ['X-Api-Token: test'],
    'url' => 'https://example.com/v2/api',
    'payload' => json_encode($payload),
];
print_r(buildOptions($input));

运行这段代码后,headers会同时包含默认的Content-Type和你传入的X-Api-Token,完全符合你的预期输出。

更通用的优化实现

如果以后你还需要处理其他类似headers的数组类型选项(比如queryParams、cookies这类可能需要合并的数组),可以把需要合并的键名做成一个白名单,让方法扩展性更好:

function buildOptions(array $options = []) {
    $supportedOptions = [
        'method' => 'POST',
        'payload' => [],
        'headers' => ['Content-Type: application/json'],
        'url' => 'https://example.com/api',
        'queryParams' => ['page' => 1], // 示例新增的需要合并的选项
    ];

    // 定义需要合并数组的键名列表
    $mergeableArrayKeys = ['headers', 'queryParams'];

    $updatedOptions = $supportedOptions;
    foreach ($options as $key => $value) {
        // 检查当前键是否在合并列表中,且传入的值是数组
        if (in_array($key, $mergeableArrayKeys) && is_array($value)) {
            $updatedOptions[$key] = array_merge($updatedOptions[$key], $value);
        } else {
            $updatedOptions[$key] = $value;
        }
    }

    return $updatedOptions;
}

这样以后新增需要合并的选项,只需要往$mergeableArrayKeys里加键名就行,不用改动核心逻辑。

额外提示

  • 如果希望自定义的头排在默认头前面,只需要把array_merge($updatedOptions[$key], $value)改成array_merge($value, $updatedOptions[$key])即可。
  • 代码里的is_array($value)判断是为了防止传入非数组类型的headers导致报错,比如误传字符串时会直接覆盖默认值,避免程序崩溃。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 05:17:46