迭代PHP数组中的所有项和子项

Iterate over all items and sub items in a PHP array

我有一个巨大的PHP数组,它保存着站点的导航结构。基本上是这样的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$navMap = array(
    array(
        'title' => 'Home',
    ), array(
        'title' => 'about us',
        'subNav' => array(
            array(
                'title' => 'Sub item 1',
                'subNav' => array(
                    array(
                        'title' => 'Sub sub item 1',
                    ),  array (
                        'title' => 'Sub sub item 2',
                    )
                ),
            ), array (
                'title' => 'Sub item 2',
            ), array (
                'title' => 'Sub item 3',
            )
        )
    )
);

我有一个文件夹结构,可以使"子项目2"页面链接/pages/1/0/1.php,因为它位于主导航项目的第二个、辅助导航项目的第一个和第三个导航项目的第二个。

我没有将链接写入容易出现人为错误的数组,而是使用PHP为我添加链接。这就是我现在正在做的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
for ($a = 0; $a < count($navMap); $a++) {
    $navMap[$a]['link'] = '/pages/'.$a.'.php';

    if (isset($navMap[$a]['subNav'])){

        for ($b = 0; $b < count($navMap[$a]['subNav']); $b++) {
            $navMap[$a]['subNav'][$b]['link'] = '/pages/'.$a.'/'.$b.'.php';

            if (isset($navMap[$a]['subNav'][$b]['subNav'])){

                for ($c = 0; $c < count($navMap[$a]['subNav'][$b]['subNav']); $c++) {
                    $navMap[$a]['subNav'][$b]['subNav'][$c]['link'] = '/pages/'.$a.'/'.$b.'/'.$c.'.php';
                }
            }

        }
    }
}

不过,这是一个非常丑陋的解决方案。有人知道向数组添加链接的更好方法吗?

我正在寻找一种解决方案,它可以自己检测无限多的级别,而不必为每添加一个额外的级别添加额外的代码。每次将新级别添加到$navmap时,都必须编辑我当前的解决方案。


您可能需要一个递归的解决方案,而不是迭代的。

1
2
3
4
5
6
7
8
9
function build_navMap(&$navMap,$link) {
    foreach ($navMap as $l => &$nm) {
        $nm['link'] ="$link/$l.php";
        if (isset ($nm['subNav'])) {
            build_navMap($nm['subNav'],"$link/$l");
        }
    }
}
build_navMap($navMap,"/pages");

此函数为数组的每个级别调用自身。一开始,递归可能有点难理解,但把它看作是一个新的干净的板岩,每次调用一个函数时,要遍历的剩余数组(传入的参数)要少一些。


可以使用foreach循环和字符串插值:

1
2
3
4
5
6
7
8
9
10
11
12
13
foreach ($navMap as $a => &$nm) {
    $nm['link'] ="/pages/$a.php";
    if (isset ($nm['subNav'])) {
        foreach ($nm['subNav'] as $b => &$sn) {
            $sn['link'] ="/pages/$a/$b.php";
            if (isset ($sn['subNav'])) {
                foreach ($sn['subNav'] as $c => &$sn2) {
                    $sn2['link'] ="/pages/$a/$b/$c.php";
                }
            }
        }
    }
}

foreach在不使用计数器的情况下迭代(但如果需要,您可以访问它们,如使用"$A=>"构造所示)。

&;$NM访问实际变量而不是副本,以便您可以分配给它。

字符串插值允许您构造更可读的字符串,而不必使用串联。