PHP - 使用点语法查找数组内容

5
有人看到以下函数有问题吗?(编辑:不,我认为没有任何问题,我只是再次检查,因为这将被插入到非常常见的代码路径中。)
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"

into:

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

为了更好地理解,我正在构建一个Smarty表单工具。我需要表单的名称,因此字符串必须以键值形式存在,并且不能直接在Smarty中访问Smarty变量。


1
没有。那个函数应该没问题吧? - echo
@echo,不,看上面的编辑。我只是不确定是否漏掉了一些非常明显的东西,或者为什么不能按照我现在的方式进行操作,或者是否有更简单的方法可以完成它。 - Nicole
5个回答

8

尝试迭代方法:

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;
}

我喜欢它...只会发生一次explode的使用,而且没有strstr检查。比我的代码少得多的字符串解析。 - Nicole

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测试。


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

在当前形式下,如果一个或多个元素不存在,将不会显示任何错误/警告

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]]...中访问不存在的元素不会引发警告消息,这使得调试和查找例如拼写错误变得非常困难。


正确的做法是,如果它不存在,只需返回空值,就像标准数组访问一样。 - Nicole
这很好。我只是感到困惑的是,PHP本身没有发出警告。 - VolkerK

0

为什么不直接利用HTML呢?name="fruit[orange]"就足够了,可以生成一个数组。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接