$metaData = 0;
$_['a'][$metaData] = 'a';
$_['a']['aa'][$metaData] = 'aa';
$_['a']['ab'][$metaData] = 'ab';
$_['a']['ac']['aaa'][$metaData] = 'aaa';
$_['b'][$metaData][$metaData] = 'b'';
$_['b']['aa'][$metaData] = 'aa';
$_['b']['bb'][$metaData] = 'bb';
ale nic to nezmeni na tom, ze to je hnusny zacatecnicky reseni, mnohem hezci by to bylo jako iterovatelnej objekt a ten do sebe zanorovat. Samozrejme to bude mit vyssi rezii, ale pokud nejde o pole s statisici/miliony prvku, tak rozhodne na miste.
Koncept bez iteratoru, nezkouseno, jen nastrel:
<?php
class Node {
    /**
     * @var Node[]
     */
    private $nodes;
    private $name;
    public function __construct($name = null) {
        $this->nodes = array();
        $this->setName($name);
    }
    public function setName($name) {
        $this->name = $name;
    }
    public function getName() {
        return $this->name;
    }
    /**
     * @param string $key
     * @return Node|null
     */
    public function getNode($key) {
        return isset($this->nodes[$key]) ? $this->nodes[$key] : null;
    }
    public function addNode($key, Node $node) {
        $this->nodes[$key] = $node;
    }
    
    public function getNodes(){
        return $this->nodes;
    }
    
    public function getAllNodes(){
        $output = array();
        foreach($this->nodes as $key => $node){
            $output[$key] = $node;
            $output = array_merge($output, $node->getAllNodes());
        }
        return $output;
    }
}
$tree = new Node();
$tree->addNode('a', new Node('a'));
$tree->getNode('a')->addNode('aa', new Node ('aa'));
$tree->getNode('a')->addNode('ab', new Node ('ab'));
$tree->getNode('a')->addNode('ac', new Node ('ac'));
$tree->getNode('a')->getNode('ac')->addNode('aaa', new Node ('aaa'));
$tree->addNode('b', new Node('b'));
$tree->getNode('b')->addNode('aa', new Node ('aa'));
$tree->getNode('b')->addNode('bb', new Node ('bb'));
//1. demo po levelech
foreach($tree->getNodes() as $key=>$node){
    /** @var $node Node **/
    $node->getName();
    $sublist = $node->getNodes();
}
//2. vse za sebou, unikatni klice musi byt ale v celem strome
foreach($tree->getAllNodes() as $key => $node){
    //....
}