解析关联数组并在下划线上爆炸

时间:2017-03-06 05:01:08

标签: php

这看似简单,但困扰了我。我需要让$ env看起来像$期望的结果。

我尝试过多种方式使用explode和foreach循环,但一直卡住。

$env = [
    ["mysql_user"=>"user var"],
    ["mysql_pass"=>"password var"],
    ["rabbit_list_one"=>"listone var"],
    ["rabbit_list_two"=>"listtwo var"],
    ["system_var_main_deep"=>"deep this"],
    ["system_var_main_that"=>"deep that"]
];

$desiredResult = [
    "mysql" => [
        "user" => "user var",
        "pass" => "password var"
    ],
    "rabbit" => [
        "list" => [
            "one" => "listone var",
            "two" => "listtwo var"
        ]
    ],
    "system" => [
        "var" => [
            "main" => [
                "deep" => "deep this",
                "that" => "deep that"
            ]
        ]
    ]
];

2 个答案:

答案 0 :(得分:1)

仔细检查$env上的格式,因为您在$env数组中显示数组而不仅仅是键/值对。假设你的输入是正确的,并且实际上有内部数组,这应该有效:

$out = [];
foreach ($env as $piece) {
    foreach ($piece as $key => $value) {
        $key_full = explode('_', $key);
        $key_last = array_pop($key_full);
        $pointer = &$out;
        foreach ($key_full as $key_level) {
            if (!isset($pointer[$key_level])) {
                $pointer[$key_level] = [];
            }
            $pointer = &$pointer[$key_level];
        }
        $pointer[$key_last] = $value;
    }
}

答案 1 :(得分:0)

根据Netrilix的回答,这是最终的解决方案。这解决了FOO_BAR_BAX和FOO_BAR都已设置的情况。我们选择始终将数组放在字符串上。谢谢大家的帮助!

public function build() {
    $config = $_ENV;
    $out = [];
    foreach ($config as $key => $value) {
        $key_full = explode('_', $key);
        $key_last = strtolower(array_pop($key_full));
        $pointer  = &$out;

        foreach ($key_full as $key_level) {
            $key_level = strtolower($key_level);

            if (!isset($pointer[$key_level])) {
                $pointer[$key_level] = [];
            }

            $pointer = &$pointer[$key_level];
        }

        $pointer = !is_array($pointer) ? [] : $pointer;
        if (!isset($pointer[$key_last])) {
            $pointer[$key_last] = $value;
        }
    }
    return $out;
}