title: PHP - How to access a deep array's contents, building the path to it dynamically
body: <p>I am trying to build a hierarchical array in PHP, from relational database contents that are stored using a closure table.  For a given result, I will have the full path to the <code>LEAF</code> node, the below would look like my result set.</p>
  
  <p>1~root~the root node</p>
  
  <p>1~root~the root node>>>2~category1~First category</p>
  
  <p>1~root~the root node>>>3~category2~Second category</p>
  
  <p>1~root~the root node>>>2~category1~First category>>>4~subCatOfCategory1~SubCategory of Cat 1</p>
  
  <p>Anyway, those are my database results.  So I want to traverse them and build a hierarchical structure in PHP so I can convert it to JSON and render a tree in DOJO</p>
  
  <p>So as I walk through each row, I am building a "path" to the leaf because I only need to add an element to tree when the element is a "leaf"... Along that thinking I decided that I would tokenize each result, using ">>>" as the delimiter, giving me the nodes that are in that row.  Then I loop through those nodes, tokenizing each one by "~" which gives me the attributes of each node.</p>
  
  <p>So, I have a for loop to process each ROW and it basically determines that if the node being processed is NOT a leaf, add it's ID to an array that is to track the path to get to the eventual leaf that will be processed.  THEN, when I finally do arrive at the LEAF, I can call a function to insert a node, using the PATH that I've compiled along the way.</p>
  
  <p>Hopefully that all makes sense.. so I've included the code below.. Consider the second result from above.  When I have processed that entire result and am about to call the function insertNodeInTreeV2(), the arrays look as below...</p>
  
  <p><code>$fullTree</code> is an array with 1 element, indexed at [1]
  That element contains an array with four elements: <code>ID(1)</code>, <code>NAME(root)</code>, <code>Description(the root node)</code>, <code>CHILDREN(empty array)</code></p>
  
  <p><code>$pathEntries</code> is an array with only one element, (1).  That is to mean that the PATH to the LEAF node being inserted is by node [1], which is the root node.</p>
  
  <p><code>$nodeToInsert</code> is an array with four elements: <code>ID(2)</code>, <code>NAME(category1)</code>, <code>Description(First Category)</code>, <code>CHILDREN(empty array)</code></p>
  
  <p><code>$treeRootPattern</code> is a STRING that contains the Variable name I'm using to store the whole array/tree, which in this case is "fullTree".</p>
  
  <pre><code>private function insertNodeInTreeV2( array &amp;$fullTree, array $pathEntries, array $nodeToInsert, $treeRootPattern )
  {
    $compiledPath = null;
    foreach ( $pathEntries as $path ) {
      $compiledPath .= $treeRootPattern . '[' . $path . '][\'CHILDREN\']';
    }
    // as this point $compiledPath = "fullTree[1]['CHILDREN']"
    $treeVar = $$compiledPath;
  }
  </code></pre>
  
  <p>So when I make the assignment, $treeVar = $$compiledPath;, I THINK I am setting the variable $treeVar to be equal to $fullTree[1]['CHILDREN'] (which I have verified in my debugger is a valid array index).  Even if I paste the contents of $compiledPath into a new Expression in Eclipse debugger, it shows me an empty array, which makes sense because that is what's located in  $fullTree[1]['CHILDREN']</p>
  
  <p>But instead, the runtime is telling me the following error...</p>
  
  <blockquote>
    <p>troller.php line 85 - Undefined variable: fullTree[1]['CHILDREN']</p>
  </blockquote>
  
  <p>Any help on this would be greatly appreciated... And if you have a better way for me to get from the result set I described to the hierarchical array I'm trying to build, I'd be eager to adopt a better method.</p>
  
  <p>UPDATED TO ADD THE CODE THAT CALLS THE ABOVE FUNCTION -- THE FOR LOOP PROCESSES ROWS OF DATABASE RESULTS, AS DESCRIBED ABOVE</p>
  
  <pre><code>foreach ( $ontologyEntries as $entry ) {
  
          // iterating over rows of  '1~~root~~The root node&gt;&gt;&gt;2~~category1~~The first category
          $nodes = explode( '&gt;&gt;&gt;', $entry['path'] );
          $numNodes = count( $nodes ) - 1 ;
  
          $pathToNewNode = null;  // this is the path, based on ID, to get to this *new* node
          for ( $level = 0; $level &lt;= $numNodes; $level++ ) {
  
              // Parse the node out of the database search result
              $thisNode = array(
                  'ID'          =&gt; strtok($nodes[$level], '~~'),  /*   1   */
                  'NAME'        =&gt; strtok( '~~'),                 /*   Root   */
                  'DESCRIPTION' =&gt; strtok( '~~'),                 /*   This is the root node   */
                  'CHILDREN'    =&gt; array()
              );
  
              if ( $level &lt; $numNodes ) {   // Not a leaf, add it to the pathToThisNodeArray
                  $pathToNewNode[] = $thisNode['ID'];
              }
              else {
                  // processing a leaf, add it to the array
                  $this-&gt;insertNodeInTreeV2( $$treeRootPattern,  $pathToNewNode, $thisNode, $treeRootPattern );
              }
  
          }
  
      }
  </code></pre>