nnyby
nnyby

Reputation: 4668

Using a PHP array as an index path

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

Answers (2)

Yasammez
Yasammez

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

KingCrunch
KingCrunch

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

Related Questions