PHP - lookup array contents with dot syntax [closed]

帅比萌擦擦* 提交于 2019-12-23 12:26:24

问题


Does anybody see anything wrong with the following function? (Edit: no, I don't think anything is wrong, I am just double-checking since this will be inserted into a very common code path.)

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

This will essentially convert:

$data, "fruits.orange.quantity"

into:

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

For context, this is for a form utility I am building in Smarty. I need the name for the form also so I need the string to be in a key-based form, and can't directly access the Smarty variable in Smarty.


回答1:


Try an iterative approach:

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



回答2:


Take a look at this: 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]

And this class also have PHPUnit tests.




回答3:


How deep will this nesting be? PHP has a limit on recursion, seems to be ca. 2^16. Just tested this and at recursion depth 65420 PHP (5.2.9) silently failed (no error).




回答4:


In its current form no error/warnings are shown if one or more elements do not exist

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

(tested with php 5.3.1/win32).
For some reason accessing a non-existing element in getNestedVar($context[$pieces[0]]... does not raise a warning message, which makes it really hard to debug and to find e.g. a typo.




回答5:


I don't see anything wrong with that code. I've tested it as well.

Does that answer your question?

Edit: This is IMHO slightly nicer. It doesn't use recursion, and returns null in case a child of a non-array is accessed.

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

Cheers




回答6:


Why you not just make use of html.. name="fruit[orange]" is enough.. to make an array.




回答7:


Have a look @ http://github.com/projectmeta/Stingray

Allows reading and writing to an array via dot notation/syntax.

Example: http://github.com/projectmeta/Stingray#example-usage



来源:https://stackoverflow.com/questions/2286706/php-lookup-array-contents-with-dot-syntax

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!