title: Nested UL LI to PHP Array - Incorrect Output in Array
body: <p>This is a follow-up to my question yesterday - <a href="https://stackoverflow.com/questions/9016257/recursive-ul-li-to-php-multi-dimensional-array">Recursive UL LI to PHP multi-dimensional array</a> - I've almost managed to convert the HTML block to an array, though there is a slight problem that I cannot fix. When processing the HTML block below, the output array does not quite follow what has been inputted (and I cannot see where I'm going wrong and need a fresh pair of eyes!!).</p>
  
  <p>I've included the following items:</p>
  
  <ul>
  <li>HTML Block</li>
  <li>PHP Function and Processing</li>
  <li>Output</li>
  </ul>
  
  <p><strong>HTML Block</strong></p>
  
  <p>Basically takes the form of:</p>
  
  <pre><code>-A
    -B
      -C
  ----
  -D
    -E
      -F
  ----
  -G
    -H
      -I
  </code></pre>
  
  <p>As follows:</p>
  
  <pre><code>&lt;li&gt;
      &lt;ul&gt;
          &lt;li&gt;A&lt;/li&gt;
          &lt;li&gt;
              &lt;ul&gt;
                  &lt;li&gt;B&lt;/li&gt;
                  &lt;li&gt;
                      &lt;ul&gt;
                          &lt;li&gt;C&lt;/li&gt;
                      &lt;/ul&gt;
                  &lt;/li&gt;
              &lt;/ul&gt;
          &lt;/li&gt;
      &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
      &lt;ul&gt;
          &lt;li&gt;D&lt;/li&gt;
          &lt;li&gt;
              &lt;ul&gt;
                  &lt;li&gt;E&lt;/li&gt;
                  &lt;li&gt;
                      &lt;ul&gt;
                          &lt;li&gt;F&lt;/li&gt;
                      &lt;/ul&gt;
                  &lt;/li&gt;
              &lt;/ul&gt;
          &lt;/li&gt;
      &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
      &lt;ul&gt;
          &lt;li&gt;G&lt;/li&gt;
          &lt;li&gt;
              &lt;ul&gt;
                  &lt;li&gt;H&lt;/li&gt;
                  &lt;li&gt;
                      &lt;ul&gt;
                          &lt;li&gt;I&lt;/li&gt;
                      &lt;/ul&gt;
                  &lt;/li&gt;
              &lt;/ul&gt;
          &lt;/li&gt;
      &lt;/ul&gt;
  &lt;/li&gt;
  </code></pre>
  
  <p><strong>PHP Function and Processing</strong></p>
  
  <pre><code>function process_ul($output_data, $data, $key, $level_data, $level_key){
  
      if(substr($data[$key], 0, 3) == '&lt;ul'){
          // going down a level in the tree
          $level_key++;
  
          // check to see if the level key exists within the level data, else create it and set to zero
          if(!is_numeric($level_data[$level_key])){
              $level_data[$level_key] = 0;
          }
  
          // increment the key to look at the next line
          $key++;
  
          if(substr($data[$key], 0, 4) !== '&lt;/ul'){
              while(substr($data[$key], 0, 4) !== '&lt;/ul'){
                  // whilst we don't have an end of list, do some recursion and keep processing the array
  
                  $returnables = process_ul($output_data, $data, $key, $level_data, $level_key);
                  $output_data = $returnables['output'];
                  $data = $returnables['data'];
                  $key = $returnables['key'];
                  $level_data = $returnables['level_data'];
                  $level_key = $returnables['level_key'];
              }
          }
      }
  
      if(substr($data[$key], 0, 4) !== '&lt;/ul' &amp;&amp; $data[$key] !== "&lt;li&gt;" &amp;&amp; $data[$key] !== "&lt;/li&gt;"){
          // we don't want to be saving lines with no data or the ends of a list
  
          // get the array key value so we know where to save it in our array (basically so we can't overwrite anything that may already exist
          $this_key = &amp;$output_data;
          for($build_key=0;$build_key&lt;($level_key+1); $build_key++){
              $this_key =&amp; $this_key[$level_data[$build_key]];
          }
  
          if(is_array($this_key)){
              // look at the next key, find the next open one
              $this_key[(array_pop(array_keys($this_key))+1)] = $data[$key];
          } else {
              // a new entry, so nothing to worry about
              $this_key = $data[$key];
          }
          $level_data[$level_key]++;
      } else if(substr($data[$key], 0, 4) == '&lt;/ul'){
          // going up a level in the tree
          $level_key--;
      }
  
      // increment the key to look at the next line when we loop in a moment
      $key++;
  
      // prepare the data to be returned
      $return_me = array();
      $return_me['output'] = $output_data;
      $return_me['data'] = $data;
      $return_me['key'] = $key;
      $return_me['level_data'] = $level_data;
      $return_me['level_key'] = $level_key;
  
      // return the data
      return $return_me;
  }
  
  
  // explode the data coming in by looking at the new lines
  $input_array = explode("\n", $html_ul_tree_in); 
  
  // get rid of any empty lines - we don't like those
  foreach($input_array as $key =&gt; $value){
      if(trim($value) !== ""){
          $input_data[] = trim($value);
      }
  }
  
  // set the array and the starting level
  $levels = array();
  $levels[0] = 0;
  $this_level = 0;
  
  // loop around the data and process it
  for($i=0; $i&lt;count($input_data); $i){
      $returnables = process_ul($output_data, $input_data, $i, $levels, $this_level);
      $output_data = $returnables['output'];
      $input_data = $returnables['data'];
      $i = $returnables['key'];
      $levels = $returnables['level_data'];
      $this_level = $returnables['level_key'];
  }
  
  // let's see how we did
  print_r($output_data);
  </code></pre>
  
  <p><strong>Output</strong></p>
  
  <p>Note that D is in the wrong position, should be in position [0][2] - not [0][1][2], and every other position after D is out by 1 place (I'm sure you can tell by looking).</p>
  
  <p>Basically takes the form of:</p>
  
  <pre><code>-A
    -B
      -C
    -D
  ----
    -E
      -F
    -G
  ----
    -H
      -I
  </code></pre>
  
  <p>As follows:</p>
  
  <pre><code>Array
  (
      [0] =&gt; Array
          (
              [0] =&gt; &lt;li&gt;A&lt;/li&gt;
              [1] =&gt; Array
                  (
                      [0] =&gt; &lt;li&gt;B&lt;/li&gt;
                      [1] =&gt; Array
                          (
                              [0] =&gt; &lt;li&gt;C&lt;/li&gt;
                          )
  
                      [2] =&gt; &lt;li&gt;D&lt;/li&gt;
                  )
  
              [2] =&gt; Array
                  (
                      [1] =&gt; &lt;li&gt;E&lt;/li&gt;
  
                      [2] =&gt; Array
                          (
                              [1] =&gt; &lt;li&gt;F&lt;/li&gt;
                          )
  
                      [3] =&gt; &lt;li&gt;G&lt;/li&gt;
                  )
  
              [3] =&gt; Array
                  (
                      [2] =&gt; &lt;li&gt;H&lt;/li&gt;
                      [3] =&gt; Array
                          (
                              [2] =&gt; &lt;li&gt;I&lt;/li&gt;
                          )
  
                  )
  
          )
  
  )
  </code></pre>
  
  <p>Thanks for your time - any assistance in outputting the array correctly would be greatly appreciated!</p>