【问题标题】:use strings to access (potentially large) multidimensional arrays使用字符串访问(可能很大)多维数组
【发布时间】:2011-10-23 15:09:19
【问题描述】:

我无法找到一种方法来简单地解析字符串输入并在多维数组中找到正确的位置。

我希望用一两行代码来做到这一点,因为我看到的解决方案依赖于长(10-20 行)循环。

给定以下代码(请注意,嵌套可以在理论上具有任意深度):

function get($string)
{
    $vars = array(
        'one' => array(
            'one-one' => "hello",
            'one-two' => "goodbye"
        ),
        'two' => array(
            'two-one' => "foo",
            'two-two' => "bar"
        )
    );

    return $vars[$string]; //this syntax isn't required, just here to give an idea
}

get("two['two-two']");  //desired output: "bar".  Actual output: null

是否可以简单地使用内置函数或其他简单的方法来重新创建我想要的输出?

【问题讨论】:

  • 不要将“无限”与“任意大”混淆。没有无限的自然数,但有任意大的自然数。
  • get("two['two-two']")$vars['two']['two-two'] 好多少?
  • 建议的语法是必需的吗? get(array('two', 'two-two')); 怎么样?
  • 恕我直言,这个问题表明你有一个严重的设计问题。
  • @David Chan,感谢您的意见。你能详细说明一下吗?

标签: php arrays string multidimensional-array


【解决方案1】:

考虑到 $vars 是您希望从 (Demo) 获取 one['one-one']two['two-two']['more'] 的变量:

$vars = function($str) use ($vars)
{
    $c = function($v, $w) {return $w ? $v[$w] : $v;};
    return array_reduce(preg_split('~\[\'|\'\]~', $str), $c, $vars);
};
echo $vars("one['one-one']"); # hello
echo $vars("two['two-two']['more']"); # tea-time!

这是将字符串词法分析为 key 标记,然后在 $vars 数组已转换为函数时遍历 keyed 值上的 $vars 数组。


老东西:

使用仅 eval 的函数重载数组:

$vars = array(
    'one' => array(
        'one-one' => "hello",
        'one-two' => "goodbye"
    ),
    'two' => array(
        'two-one' => "foo",
        'two-two' => "bar"
    )
);

$vars = function($str) use ($vars)
{
    return eval('return $vars'.$str.';');
};

echo $vars("['one']['one-two']"); # goodbye

如果您不喜欢 eval,请更改实现:

$vars = function($str) use ($vars)
{
    $r = preg_match_all('~\[\'([a-z-]+)\']~', $str, $keys);
    $var = $vars;
    foreach($keys[1] as $key)
        $var = $var[$key];
    return $var;
};
echo $vars("['one']['one-two']"); # goodbye

【讨论】:

    【解决方案2】:

    怎么样

    $vars = array(
        'one' => array(
            'one-one' => "hello",
            'one-two' => "goodbye"
        ),
        'two' => array(
            'two-one' => "foo",
            'two-two' => "bar"
        )
    );
    
    function get( $string, $vars )
    {
        $keys = explode( '][', substr( $string, 1, -1 ) );
        foreach( $keys as $key ) {
            $vars = $vars[$key];
        }
        return $vars;
    }
    
    echo get( '[two][two-one]', $vars );
    

    【讨论】:

      【解决方案3】:

      首先,您的get() 函数中没有$var。 $var 是在函数外部定义的,PHP 范围规则不会使“更高”的变量在更低的范围内可见,除非明确在更低的范围内设为全局:

      function get($string) {
         global $vars;
         eval('$x = $vars' . $string);
         return $x;
      }
      
      get("['two']['two-two']");
      

      可能有效,但这没有经过测试,而且使用 eval 几乎总是一个非常糟糕的主意。

      【讨论】:

      • 我在其他地方看到了eval() 的答案,这实际上将我的问题的答案减少到了一行。但是...是的,我对eval() 非常警惕。修复范围问题...
      • 把'换成"会出很多问题
      【解决方案4】:

      Kohana 有一个很好的 Config 类,它允许这样的事情:

      echo Config::get("two.two-two");
      

      您可以在这里查看:http://kohanaframework.org/3.1/guide/api/Config

      【讨论】:

        猜你喜欢
        • 2015-06-16
        • 2023-03-17
        • 2011-04-28
        • 1970-01-01
        • 1970-01-01
        • 2013-01-20
        • 1970-01-01
        • 2016-06-10
        • 1970-01-01
        相关资源
        最近更新 更多