I'm currently rewriting a navigation structure to be sorted by size into multiple columns, when I encountered some unexpected behavior, which I've successfully recreated here.
I'm creating an array with several items, also arrays. the items contain a name and might contain an array sub which is an array of more items. This has the possibility to be nested into infinity.
The list will be displayed in HTML as a multiple layered ul.
Using a recusive function would make sense in this case. As mentioned before the list will be sorted by size later on, for that reason I created the variable $index which is supposed to count the total amount of items in the current list, but instead of continuing to count after one level is completed PHP decides to use the previous iteration before the function was opened recusively.
Code, Output and expexted output below.
My Question: Is there a way to iterate the variable $index through the whole function?
PHP Code:
<!-- language: php -->
<?php
$lists = [
[
'name' => 'level0-item',
'sub' => [
['name' => 'level1-item'],
['name' => 'level1-item'],
['name' => 'level1-item'],
[
'name' => 'level1-item',
'sub' => [
['name' => 'level2-item'],
['name' => 'level2-item'],
]
],
[
'name' => 'level1-item',
'sub' => [
['name' => 'level2-item'],
['name' => 'level2-item'],
]
],
]
],
[
'name' => 'level0-item',
'sub' => [
['name' => 'level1-item'],
['name' => 'level1-item'],
['name' => 'level1-item'],
]
]
];
function handleLists($lists, $index = 0, $level = 0) {
echo '<ul>';
foreach ($lists as $list) {
echo '<li>';
$index++; // increas index
echo $list['name'] . ' - level: ' . $level . ' - index: ' . $index;
if ($list['sub'])
handleLists($list['sub'], $index, $level+1); // recursive call
echo '</li>';
}
echo '</ul>';
}
handleLists($lists);
?>
Output:
- level0-item - level: 0 - index: 1
- level1-item - level: 1 - index: 2
- level1-item - level: 1 - index: 3
- level1-item - level: 1 - index: 4
- level1-item - level: 1 - index: 5
- level2-item - level: 2 - index: 6
- level2-item - level: 2 - index: 7
- level1-item - level: 1 - index: 6
- level2-item - level: 2 - index: 7
- level2-item - level: 2 - index: 8
- level0-item - level: 0 - index: 2
- level1-item - level: 1 - index: 3
- level1-item - level: 1 - index: 4
- level1-item - level: 1 - index: 5
Expected output:
- level0-item - level: 0 - index: 1
- level1-item - level: 1 - index: 2
- level1-item - level: 1 - index: 3
- level1-item - level: 1 - index: 4
- level1-item - level: 1 - index: 5
- level2-item - level: 2 - index: 6
- level2-item - level: 2 - index: 7
- level1-item - level: 1 - index: 8
- level2-item - level: 2 - index: 9
- level2-item - level: 2 - index: 10
- level0-item - level: 0 - index: 11
- level1-item - level: 1 - index: 12
- level1-item - level: 1 - index: 13
- level1-item - level: 1 - index: 14
Addition
I could have understood nested foreach-/for-loops incorrectly, here is some hopefully understandable pseudocode, i gets increased by 1 every time a new foreach opens.
Expected behavior:
i = 0
// step 1
foreach1 opens i = 1
// step 2
foreach1
__foreach2 opens i = 2
// step 3
foreach1
__foreach2
foreach1 opens i = 3
// step 4
foreach1
__foreach2
foreach1
__foreach2 opens i = 4
Apparent behavior:
i = 0
// step 1
foreach1 opens i = 1
// step 2
foreach1
foreach1 opens i = 2
// step 3
foreach1
__foreach2 opens i = 2 (cause previous foreach1 i = 1)
foreach1
// step 4
foreach1
__foreach2
foreach1
__foreach2 opens i = 3 (cause previous foreach1 i = 2)