Tutorial :PHP - lookup array contents with dot syntax [closed]



Question:

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.


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


Solution: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.


Solution: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).


Solution: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.


Solution: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


Solution:6

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


Solution: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


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »