Reputation: 4668
I have a hierarchical array path in a flat PHP array, e.g.: $path = array('fruit', 'banana', 'fresh');
I define my multidimensional array as $tree
. How would you use $path
to set/get the appropriate node in $tree
? $tree[$path] = 'blablabl';
throws an "Illegal offset error". I'm not sure how I would implode() the path to a string and use eval() to get the index. What's the most straightforward way to do this?
Upvotes: 3
Views: 494
Reputation: 1561
I solved the same problem with references:
function &walk_path(array &$root, array $path)
{
$cursor = &$root;
foreach ($path as $e) { $cursor = &$cursor[$e]; }
return $cursor;
}
$db = [];
$tmp = &walk_path($db, ["users","deanna", "favourite food"]);
$tmp = "chocolate";
print_r($db);
will produce
Array
(
[users] => Array
(
[deanna] => Array
(
[favourite food] => chocolate
)
)
)
Note that since PHP autovivicates this will create any non-existent keys either as an array with the only key being the next elemenet in the path or null if it is the leaf node. This is fortunately exactly the behaviour I needed. However, it still strikes me as a bit akward that I have to write this function myself in a lanuage so focused on its arrays. Any suggestions to make this shorter are very welcome.
Upvotes: 2
Reputation: 132021
Because an array is an array and PHP doesn't know anything about trees you must resolve the path against your multidimensional array yourself, but thats not hard.
Iterativ
$result = $tree;
foreach ($path as $step) {
$result = $result[$step];
}
or recursive
function resolve_tree ($tree, $path) {
return empty($path)
? $tree
: resolve_tree ($tree[$path[0]], array_slice($path, 1));
}
Note, that this are the simplest solutions. For example you should take care, that a given key from $path
exists, before you try to access it.
Update: I overlooked the "set"-part in the question. Without references its not that funny, thus I suggest to completely switch over to objects instead of arrays. Its not required, that you create a class. You can simply use stdClass
. This would even feel a little bit more "tree"ish
Upvotes: 3