Ivan Ivan - 4 days ago 6
PHP Question

php recursive looping not repeat divider

I have problem with recrusive looping. I have db table

site_pages
where i store web pages (cms) and that pages can have parent whitch is related with
parent_id
in the some table.

Generally want to achieve this effect with these retractable.

|—
if is root if has one children

|—|—
if has two children

|—|—|—
three childrens ...

enter image description here

Above is effect what i want. But in my case i get this effect. There is not repeated two dividers before page title.

enter image description here

Here is my array what i loop :

Array
(
[0] => Array
(
[id] => 1
[title] => Home
)

[1] => Array
(
[id] => 2
[title] => About us
[children] => Array
(
[0] => Array
(
[id] => 5
[title] => Subpage #1
[children] => Array
(
[0] => Array
(
[id] => 6
[title] => Subpage #2
)


)

)

)

)


Code where i loop
pages
array:


<table class="table table-striped table-bordered">
<thead>
<tr>
<th>Page name</th>
<th>Status</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php if($pages): ?>

<?php foreach ($pages as $index => $page): ?>
<tr>
<td><span class="gi">|—</span><?= $page['title'];?></td>
<td><?= $page['status'];?></td>
<td>N/A</td>
</tr>
<?php if(!empty($page['children'])): ?>
<?= fetchChilds($page['children']); ?>
<?php endif;?>

<?php endforeach; ?>

<?php endif; ?>
</tbody>
</table>


And here is child looping helper function:

function fetchChilds($pages) {

$html = "<tr>";

foreach ($pages as $child) {

$html .= '<td> <span class="gi">|—</span>'. $child["title"] .'</td>';
$html .= '<td>'. $child["status"] .'</td>';
$html .= '<td> N/A</td>';

if(isset($child['children'])) {
$html .= fetchChilds($child['children']);
}
}

$html .= "</tr>";

return $html;
}

Seb Seb
Answer

No. There is no repeated divider in the output. Because every table row (why do you use tables for this?) contains only the one |- prefix.

Without complety rewriting your code, the only idea I have is to add a level-param to fetchChilds.

function fetchChilds($pages, $level) {

    foreach ($pages as $child) {
        $html = "<tr>";
        $html .= '<td> <span class="gi">'. str_repeat("|-", $level); .'</span>'. $child["title"] .'</td>';
        $html .= '<td>'. $child["status"] .'</td>';
        $html .= '<td> N/A</td>';
        $html .= "</tr>";

        if(isset($child['children'])) {
            $html .=  fetchChilds($child['children'], $level+1);
        }
    }

    return $html;
}

And then you need to add a level to your other code:

<?php if($pages): ?>
   <?php foreach ($pages as $index => $page): ?>
       <tr>
           <td><span class="gi">|—</span><?= $page['title'];?></td>
           <td><?= $page['status'];?></td>
           <td>N/A</td>
        </tr>
        <?php if(!empty($page['children'])): ?>
            <?= fetchChilds($page['children'],2); ?>
        <?php endif;?>
   <?php endforeach; ?>
<?php endif; ?>

If you make that step, you might realize that your topmost array level is level 1 and could be used in fetchChilds as well:

<?php if($pages): ?>
   <?php foreach ($pages as $index => $page): ?>
       <?= fetchChilds($page,1); ?>
   <?php endforeach; ?>
<?php endif; ?>
Comments