Как получить вложенный список HTML из набора записей массива объекта? - PullRequest
5 голосов
/ 05 ноября 2011

У меня есть этот массив объектов, возвращаемых SQL-запросом, где top_id - это поле моего родительского идентификатора:

Array (
[0] => stdClass Object ( [id] => 1 [top_id] => 0 [name] => Cat 1 )
[1] => stdClass Object ( [id] => 2 [top_id] => 0 [name] => Cat 2 ) 
[2] => stdClass Object ( [id] => 3 [top_id] => 0 [name] => Cat 3 ) 
[3] => stdClass Object ( [id] => 4 [top_id] => 2 [name] => Subcat 1 ) 
[4] => stdClass Object ( [id] => 5 [top_id] => 2 [name] => Subcat 2 ) 
[5] => stdClass Object ( [id] => 6 [top_id] => 3 [name] => Subcat 3 ) 
[6] => stdClass Object ( [id] => 7 [top_id] => 5 [name] => Subcat 4 )
)

Теперь мне нужно получить вложенный список, например, с помощью PHP:

<ul>
  <li>Cat 1</li>
  <li>Cat 2
    <ul>
      <li>Subcat 1</li>
      <li>Subcat 2
        <ul>
          <il>Subcat 3
            <ul>
              <li>Subcat 4</li>
            </ul>
          </li>
        </ul>
      </li>
    </ul>
  </li>
  <li>Cat 3</li>
</ul>

Есть идеи? Спасибо

1 Ответ

9 голосов
/ 05 ноября 2011

Прежде всего отобразите объекты на новый хеш (массив), индекс которого равен id:

// map the array onto hash
$hash = array();
foreach($array as $object)
{
    $hash[$object->id] = array('object' => $object);
}

Затем перенесите этот плоский хеш в древовидную структуру, посмотрите этот ответ для другого примера кода , здесь он просто такой же:

// build tree from hash
$tree = array();
foreach($hash as $id => &$node)
{
    if ($parent = $node['object']->top_id)
        $hash[$parent]['children'][] =& $node;
    else
        $tree[] =& $node;
}
unset($node, $hash);

Наконец, вы можете вывести эту древовидную структуру в виде HTML. Это можно сделать с помощью стека или рекурсивно. Это один вариант с рекурсией:

// render tree
function render_tree($tree)
{
    echo '<ul>', "\n";
    foreach($tree as $node)
    {
        render_node($node);
    }
    echo '</ul>';
}

// render tree node
function render_node($node, $level = 0)
{
    $inset = str_repeat('    ', $level) . '  ';
    echo $inset, '<li>', $node['object']->name;
    if (isset($node['children']))
    {
        echo "\n", $inset, '  <ul>', "\n";
        foreach($node['children'] as $node)
        {
            render_node($node, $level+1);
        }
        echo $inset, '  </ul>', "\n", $inset;
    }
    echo '</li>', "\n";
}

// output
render_tree($tree);

Выход:

<ul>
  <li>Cat 1</li>
  <li>Cat 2
    <ul>
      <li>Subcat 1</li>
      <li>Subcat 2
        <ul>
          <li>Subcat 4</li>
        </ul>
      </li>
    </ul>
  </li>
  <li>Cat 3
    <ul>
      <li>Subcat 3</li>
    </ul>
  </li>
</ul>

Полный код Пример + HTML Demo .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...