问题
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