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

Laravel 10.x中基于点符号递归设置PHP数组键值对的实现问题

Laravel 10.x中基于点符号递归设置PHP数组键值对的实现问题

我明白你想要做的事:通过带点分隔的键名(比如http.retries.attempts)递归地修改你的$options数组,同时保留那些没被指定的默认值,而且如果嵌套键不存在的话还要自动创建。你的代码思路是对的,但核心问题出在数组引用的处理上——你直接把$this->options替换成了子数组,导致最后没法把值设置回原数组的正确位置。

来看看修正后的实现,我会一步步解释:

/**
 * Set the options for the tier
 */
public function setOptions(array $options = []): void
{
    foreach ($options as $option) {
        $name = $option['name'];
        $value = $option['value'];
        
        // 没有点分隔的键,直接赋值
        if (!str_contains($name, '.')) {
            $this->options[$name] = $value;
            continue;
        }

        $nameParts = explode('.', $name);
        // 使用引用跟踪当前层级的数组,初始指向原options数组
        $current = &$this->options;

        // 遍历所有键段,除了最后一个
        foreach ($nameParts as $index => $part) {
            // 如果不是最后一个键段,确保当前层级存在数组
            if ($index !== count($nameParts) - 1) {
                if (!isset($current[$part]) || !is_array($current[$part])) {
                    $current[$part] = [];
                }
                // 把引用移到下一层级的数组
                $current = &$current[$part];
            } else {
                // 最后一个键段,直接设置值
                $current[$part] = $value;
            }
        }

        // 取消引用,避免后续操作意外修改数组
        unset($current);
    }
}

关键改进点:

  • 使用&$current引用变量来跟踪当前操作的数组层级,这样所有修改都会直接作用于原$this->options数组,而不会像你之前那样把原数组替换成子数组。
  • 区分了最后一个键段和前面的键段:前面的键段负责创建不存在的嵌套数组,最后一个键段负责设置具体的值。
  • 操作完成后取消引用,防止后续代码不小心复用这个引用导致的意外问题。

测试验证

用你提供的示例选项(http.method和http.url)运行这个方法后,你的$this->options数组会保留所有默认值,同时覆盖指定的字段:

[
    'http' => [
        'method' => 'post', // 被覆盖的值
        'url' => 'https://example.com/', // 被覆盖的值
        'timeout' => 60, // 保留默认值
        'connect_timeout' => null, // 保留默认值
        'options' => null, // 保留默认值
        'headers' => null, // 保留默认值
        'as_form' => null, // 保留默认值
        'retries' => [
            'attempts' => null,
            'backoff' => 100
        ],
        'authentication' => [
            'is_required' => null,
            'username' => null,
            'password' => null // 这里注意你原代码里写的是`>`,应该是`=>`,记得修正这个笔误
        ],
        'query' => [
            'with_params' => null,
            'params' => null
        ],
    ]
];

另外提醒你一下,原代码里的'password' > null是语法错误,要改成'password' => null哦。

备注:内容来源于stack exchange,提问作者Ryan H

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.21 11:59:36