PHP数组将带点号的键解析为多维数组

时间:2018-09-26 08:38:43

标签: php arrays recursion

我正在处理一些数组问题。我所拥有的是函数arr_set(),我可以在其中传递数组,键和值(例如,在键“ sub.key”上设置值“ value”,这将创建具有值“ {值”。 我还可以直接设置一个数组(然后是$array["sub"]["key"]的值,而$key为null)并分配它-也可以工作,但其中有一个小错误,因为它不会分割点标记的键位于某个子数组中的某个地方。

检查代码:

$value

结果是

/**
 * Function to set the data
 *
 * @param      $array
 * @param      $key
 * @param null $value
 */
function arr_set(&$array, $key, $value = null) {
    if ($key === null) {
        $array[] = $value;

        return;
    }

    if (is_array($key)) {
        foreach ($key as $k => $v) {
            arr_set($array, $k, $v);
        }

        return;
    }

    $temp = &$array;
    $key = (string)$key;
    $keys = explode(".", $key);
    foreach ($keys as $k) {
        if ((is_array($temp) && !array_key_exists($k, $temp)) || !is_array($temp[$k])) {
            $temp[$k] = [];
        }
        $temp = &$temp[$k];
    }

    $temp = $value;
}

$temp = [
    "live" => [
        "db.name" => "livedb",
        "db"       => [
            "host" => "localhost",
        ],
    ],
];

# Original array
$myArray = [];

# Set the $temp to the $myArray
arr_set($myArray, $temp);

echo "<pre>" . print_r($myArray, true) . "</pre>";

几乎,但不是很完美-您看到“ db.name”键了吗?这实际上不应该存在,但是键“ db”应该具有与“主机”相同级别的子键“名称”。希望我能提供足够的信息使问题易于理解。 关于如何解决这个小错误的思考使我的大脑不知所措,我得出的结论是,如果有解决方案,它将导致超级混乱,糟糕透顶,骇人听闻的一段糟糕的代码。希望不会,但是我放弃了这一点^^

我在Google上搜索和搜索了很多,但是找不到任何可行的解决方案。这个库https://github.com/adbario/php-dot-notation无法做到,而laravel的Array ( [live] => Array ( [db.name] => livedb [db] => Array ( [host] => localhost ) ) ) 也无法做到。有什么想法吗?

(PS:很抱歉英语不好,这里是德语)

1 个答案:

答案 0 :(得分:0)

我创建了一个简单的解决方案,该方案不考虑某些极端情况或错误处理,但是如果您要使用递归解决方案,则可以从这个方向开始。我们也可以使用您的字符串参数创建一个递归函数,但是使用起来很困难,因此我为此创建了第二个函数,它使用了爆炸数组。我们立即使用它,爆炸了键串。

function arr_set(array &$array, $key, $value)
{
    $keys = explode(".", $key);
    arr_set_recursive($array, $keys, $value);
}

在递归中,我们传递给我们使用的数组,剩下的键和要插入的值。我们必须从递归中退出,以防止错误或堆栈溢出,因此我们检查是否还有键。在每个步骤中,我们从keys数组中移出一个键。所以首先我们有“ db”,然后是“ name”。我们还要检查这里是否还有其他键。如果不这样做,则将值设置为先前移动的键。否则,我们会更深一步,然后重复整个过程。

function arr_set_recursive(array &$array, array $keys, $value)
{
    if (count($keys) > 0) {
        $key = array_shift($keys);
        if (count($keys) == 0) {
            $array[$key] = $value;
        } else {
            if (!array_key_exists($key, $array)) {
                $array[$key] = [];
            }
            arr_set_recursive($array[$key], $keys, $value);
        }
    }
}

您可以在此处查看解决方案:http://sandbox.onlinephpfunctions.com/code/758bd7ed7c3cfc5bc33b4f06317be97b83958771