在模板中调用多维关联数组

1 php

我正在构建一个小模板系统,我正在寻找一种使用点调用多维关联数组的方法.例如:

$animals = array(
          'four-legged' => array (
                          'cute' => 'no',
                          'ugly' => 'no',
                          'smart' => array('best' => 'dog','worst' => 'willy')
                          ),
          '123' => '456',
          'abc' => 'def'
);
Run Code Online (Sandbox Code Playgroud)

然后,在我的模板中,如果我想展示'狗',我会说:

{} a.four-legged.smart.best

irc*_*ell 5

好吧,给出一个字符串four-legged.smart.worst:

function getElementFromPath(array $array, $path) {
    $parts = explode('.', $path);
    $tmp = $array;
    foreach ($parts as $part) {
        if (!isset($tmp[$part])) {
            return ''; //Path is invalid
        } else {
            $tmp = $tmp[$part];
        }
    }
    return $tmp; //If we reached this far, $tmp has the result of the path
}
Run Code Online (Sandbox Code Playgroud)

所以你可以打电话:

$foo = getElementFromPath($array, 'four-legged.smart.worst');
echo $foo; // willy
Run Code Online (Sandbox Code Playgroud)

如果你想编写元素,那就不难了(你只需要使用引用,如果路径不存在,可以通过一些检查来默认值)...:

function setElementFromPath(array &$array, $path, $value) {
    $parts = explode('.', $path);
    $tmp =& $array;
    foreach ($parts as $part) {
        if (!isset($tmp[$part]) || !is_array($tmp[$part])) {
            $tmp[$part] = array();
        }
        $tmp =& $tmp[$part];
    }
    $tmp = $value;
}
Run Code Online (Sandbox Code Playgroud)

编辑:由于这是在模板系统中,将数组"编译"到单个维度一次,而不是每次遍历它(出于性能原因)可能是值得的...

function compileWithDots(array $array) {
    $newArray = array();
    foreach ($array as $key => $value) {
        if (is_array($value)) {
            $tmpArray = compileWithDots($value);
            foreach ($tmpArray as $tmpKey => $tmpValue) {
                $newArray[$key . '.' . $tmpKey] = $tmpValue;
            }
        } else {
            $newArray[$key] = $value;
        }
    }
    return $newArray;
}
Run Code Online (Sandbox Code Playgroud)

所以这将转换:

$animals = array(
 'four-legged' => array (
  'cute' => 'no',
  'ugly' => 'no',
  'smart' => array(
   'best' => 'dog',
   'worst' => 'willy'
  )
 ),
 '123' => '456',
 'abc' => 'def'
);
Run Code Online (Sandbox Code Playgroud)

array(
    'four-legged.cute' => 'no',
    'four-legged.ugly' => 'no',
    'four-legged.smart.best' => 'dog',
    'four-legged.smart.worst' => 'willy',
    '123' => '456',
    'abc' => 'def',
);
Run Code Online (Sandbox Code Playgroud)

然后你的查找就变成$value = isset($compiledArray[$path]) ? $compiledArray[$path] : '';$value = getElementFromPath($array, $path);

它交换预计算内联速度(循环内的速度)......