Как создать логическое повторение для корня ветки в Stack Overflow

Я хотел бы создать повторение логики для повторения и сделать ветку на php, результат будет таким (это без логики повторения просто HTML):

    <ul>
<li>
<a href="#">Parent</a>
<ul>
<li>
<a href="#">Child</a>
<ul>
<li>
<a href="#">Grand Child</a>
</li><li>
<a href="#">Grand Child</a>
<ul>
<li>
<a href="#">Grand Grand Child</a>
</li><li>
<a href="#">Grand Grand Child</a>
</li>
</ul>
</li>
</ul>
</li><li>
<a href="#">Child</a>
<ul>
<li>
<a href="#">Grand Child</a>
<ul>
<li>
<a href="#">Grand Grand Child</a>
</li>
</ul>
</li><li>
<a href="#">Grand Child</a>
</li>
</ul>
</li>
</ul>
</li>
</ul>

0

Решение

Это делается с помощью рекурсивной функции и вложенного массива, через который вы затем проходите. Следующая функция может пройти n уровней без проблем.

<?php
function makeNav($item) {
$ret = '<li><a href="'.$item['url'].'">'.$item['name'].'</a>'.PHP_EOL;

if (isset($item['subPgs']) && is_array($item['subPgs']) && count($item['subPgs']) > 0) {
$ret .= '<ul>'.PHP_EOL;
foreach ($item['subPgs'] as $subPg) {
$ret .= makeNav($subPg);
}
$ret .= '</ul>'.PHP_EOL;
} else {
$ret .= '</li>'.PHP_EOL;
}

if (isset($item['subPgs']) && is_array($item['subPgs']) && count($item['subPgs']) > 0) {
$ret .= "</li>".PHP_EOL;
}

return $ret;
}

$navItems = array(
/*array(
'name' => 'Home',
'url' => '#',
'subPgs'=>array()
),*/
array(
'name' => 'Parent',
'url' => '#',
'subPgs' => array(
array(
'name' => 'Child',
'url' => '#',
'subPgs' => array(
array(
'name' => 'Grand Child',
'url' => '#'
),
array(
'name' => 'Grand Child',
'url' => '#',
'subPgs' => array(
array(
'name' => 'Grand Child Child',
'url' => '#'
),
array(
'name' => 'Grand Child Child',
'url' => '#'
)
)
)
)
),
array(
'name' => 'Child',
'url' => '#',
'subPgs' => array(
array(
'name' => 'Grand Child',
'url' => '#',
'subPgs' => array(
array(
'name' => 'Grand Grand Child',
'url' => '#'
)
)
),
array(
'name' => 'Grand Child',
'url' => '#'
)
)
)
)
)
);

$nav = '<ul>';
foreach ($navItems as $navItem) {
$nav .= makeNav($navItem);
}
echo $nav.'</ul>';
?>

Выходы: (что соответствует OP, кроме форматирования)

<ul>
<li>
<a href="#">Parent</a>
<ul>
<li>
<a href="#">Child</a>
<ul>
<li>
<a href="#">Grand Child</a>
</li>
<li>
<a href="#">Grand Child</a>
<ul>
<li>
<a href="#">Grand Child Child</a>
</li>
<li>
<a href="#">Grand Child Child</a>
</li>
</ul>
</li>
</ul>
</li>
<li>
<a href="#">Child</a>
<ul>
<li>
<a href="#">Grand Child</a>
<ul>
<li>
<a href="#">Grand Grand Child</a>
</li>
</ul>
</li>
<li>
<a href="#">Grand Child</a>
</li>
</ul>
</li>
</ul>
</li>
</ul>

Смотрите это онлайн: https://3v4l.org/O4i2t

1

Другие решения

Помните, что если ваш набор данных большой или код становится более сложным, чем простая текстовая строка в каждом элементе списка, вы можете кэшировать результаты своей рекурсивной функции и восстанавливать дерево только при обновлении данных.

Я бы передавал текущий родительский идентификатор, если бы знал, что могу получить доступ к детям каждого из родителей через какую-то другую функцию. Когда это работает, рекурсия всегда хитра и обманчиво проста.

// assuming getChildIds( $parentId ) is a function that returns an array of ids
// assuming getName( $id ) is a function that returns a name.
// If you actually want "Parent", "Child", ... "Grand Grand ... Grand Child"// add a generation parameter to the recursive function and figure it out that way.

function echo_child_node( $parentId ) { ?>
<li>
<a href="#"><?php echo getName( $parentId ) ?></a>
<?php $childIds = getChildIds( $parentId ); ?>
<?php if ( $childIds ) : ?>
<ul>
<?php foreach( $childIds as $childId ) :
echo_child_node( $childId );
} ?>
</ul>
<?php endif; ?>
</li>
<? }
1

По вопросам рекламы [email protected]