2010-02-18 35 views
4

有人看到以下函数有什么问题吗? (编辑:没有,我觉得没有什么是错的,我只是双重检查,因为这会被插入到一个非常常见的代码路径。)PHP - 使用点语法查找数组内容

function getNestedVar(&$context, $name) { 
    if (strstr($name, '.') === FALSE) { 
     return $context[$name]; 
    } else { 
     $pieces = explode('.', $name, 2); 
     return getNestedVar($context[$pieces[0]], $pieces[1]); 
    } 
} 

这将从根本上转变:

$data, "fruits.orange.quantity" 

到:

$data['fruits']['orange']['quantity'] 

对于背景下,这是一种形式公用事业我建立在Smarty的。我也需要表单的名称,所以我需要字符串是基于键的形式,并且不能直接访问Smarty中的Smarty变量。

+1

没有。那个功能应该有问题吗? – echo 2010-02-18 06:34:29

+0

@echo,不,请参阅上面的编辑。我只是不确定我是否错过了一些完全明显的事情,为什么不按照我的方式来做,或者有更简单的方法去做。 – Nicole 2010-02-18 06:49:22

回答

7

尝试迭代方法:

function getNestedVar(&$context, $name) { 
    $pieces = explode('.', $name); 
    foreach ($pieces as $piece) { 
     if (!is_array($context) || !array_key_exists($piece, $context)) { 
      // error occurred 
      return null; 
     } 
     $context = &$context[$piece]; 
    } 
    return $context; 
} 
+0

我喜欢它......只有一次爆炸的使用会发生并且没有strstr检查。比我的方式更少的字符串解析。 – Nicole 2010-02-18 08:39:29

+0

真棒的东西谢谢。 – mattl 2015-06-04 15:14:37

0

我没有看到任何错误的代码。我也测试过它。

这是否回答你的问题?

编辑:这是恕我直言稍微好一点。它不使用递归,并且在非数组的子元素被访问的情况下返回null。

function getNestedVar(array $array, $name) { 
    $name = explode('.', $name); 
    foreach($name as $namePart) { 
     if (is_array($array)) return null; 
     if (!isset($array[$name])) return null; 
     $array = $array[$name]; 
    } 

    return $array; 
} 

干杯

0

有多深,这将是筑巢? PHP对递归有限制,似乎是ca. 2^16。只是测试了这个,并在递归深度65420 PHP(5.2.9)默默失败(没有错误)。

+0

当然不是那么深,但这是很好的知道。 – Nicole 2010-02-18 08:38:42

0

在其目前的形式,如果不存在

error_reporting(E_ALL|E_STRICT); ini_set('display_errors', 1); 
$x = array(); 
getNestedVar($x, '1.2.3.4'); 
echo 'done.'; 

一个或多个元件没有错误/警告显示(用PHP 5.3.1/win32的测试)。
由于某种原因,访问getNestedVar($context[$pieces[0]]...中的一个不存在的元素不会引发警告消息,这使得调试和查找过程非常困难。一个错字。

+0

正确...我只是希望null返回,如果它不存在,就像使用标准数组访问一样。 – Nicole 2010-02-18 08:38:15

+0

......这很好。我只是困惑,PHP本身并没有提出警告。 – VolkerK 2010-02-18 14:37:59

0

为什么你不只是使用html .. name="fruit[orange]"就足够了..做一个数组。

1

在此请看:https://gist.github.com/elfet/4713488

$dn = new DotNotation(['bar'=>['baz'=>['foo'=>true]]]); 

$value = $dn->get('bar.baz.foo'); // $value == true 

$dn->set('bar.baz.foo', false); // ['foo'=>false] 

$dn->add('bar.baz', ['boo'=>true]); // ['foo'=>false,'boo'=>true] 

这个类也有PHPUnit测试。