php:使用来自多维数组的CSS代码生成动态菜单

时间:2018-02-06 10:51:27

标签: php html css arrays multidimensional-array

我正在尝试将当前请求的页面标记为在我的菜单中处于活动状态,但似乎出现了问题......我和我的同事无法弄清楚出了什么问题......我一直在尝试现在想出这个已经超过一个星期,我已经阅读了这个和其他网站上的几十个问题和答案,但无济于事。

让我感到困惑的一件事就是$ page的值似乎从一个字符串变为一个数字,你可以通过我已经实现的调试来判断。

这是index.php的相关代码:

$pages = array('home','overons','onsteam','organisatie','diensten','aandeslag',
               'ictlab','eendagbij','opdrachtgevers','verwijzers',
               'trajectbegeleiding','contact');
if(in_array($_GET['p'], $pages)) {
    $content = $_GET['p'];
} else {
    $content = "home";
}
echo "<!-- content = ".$content." -->\n";
require($inc_path.'navbar'.$php_ext);

和navbar.php中的代码:

 $menu = array (
            'home',
            'overons'       =>  array   (
                                        'onsteam',
                                        'organisatie'
                                        ),
            'diensten'      =>  array   (
                                        'aandeslag',
                                        'ictlab',
                                        'eendagbij'
                                        ),
            'opdrachtgevers',
            'verwijzers'    =>  array   (
                                        'trajectbegeleiding'
                                        ),
            'contact'
            );
$pagenames = array (
                'home'                  =>   'Home',
                'overons'               =>   'Over Ons',
                'onsteam'               =>   'Ons Team',
                'organisatie'           =>   'Organisatie',
                'diensten'              =>   'Diensten',
                'aandeslag'             =>   'Aan De Slag',
                'ictlab'                =>   'ICT Lab',
                'eendagbij'             =>   'Een dag bij',
                'opdrachtgevers'        =>   'Opdrachtgevers',
                'verwijzers'            =>   'Verwijzers',
                'trajectbegeleiding'    =>   'Traject begeleiding',
                'contact'               =>   'Contact'
                );
function MakeMenu($menu, $currentpage, $level = 0) {
    echo "<!-- MakeMenu0: currentpage = ".$currentpage." -->\n";
    global $pagenames;
    $ret = "";
    $indent = str_repeat(" ", $level * 2);
    if ($level!=0) {
        $ret .= "<!-- MakeMenu1: Level = ".$level." -->\n";
        $ret .= sprintf("%s<ul class=\"dropdown-menu\">\n", $indent);
    } else {
        $ret .= "<!-- MakeMenu2: Level = 0 -->\n";
        $ret .= sprintf("%s<ul class=\"nav navbar-nav\">\n", $indent);
    }
    $indent = str_repeat(" ", ++$level * 2);
    foreach ($menu as $page => $subpages) {
        if (!is_numeric($page)) {
            if ($page==$currentpage) {
                $ret .= "<!-- MakeMenu3: page (".$page.") = currentpage (".$currentpage.") -->\n";
                if (is_array($subpages)) {
                    $ret .= sprintf("%s<li class=\"active dropdowm\"><a href='?p=%s'>%s<span class='caret'></span></a>", $indent, $page, $pagenames[$page]);
                } else {
                    $ret .= sprintf("%s<li class=\"active\"><a href='?p=%s'>%s</a>", $indent, $page, $pagenames[$page]);
                }
            } else {
                $ret .= "<!-- MakeMenu4: page (".$page.") != currentpage (".$currentpage.") -->\n";
                if (is_array($subpages)) {
                    $ret .= sprintf("%s<li class=\"dropdown\"><a href='?p=%s'>%s<span class='caret'></span></a>", $indent, $page, $pagenames[$page]);
                } else {
                    $ret .= sprintf("%s<li><a href='?p=%s'>%s</a>", $indent, $page, $pagenames[$page]);
                }
            }
        }
        if (is_array($subpages)) {
            $ret .= "\n";
            $ret .= MakeMenu($subpages, $currentpage, $level + 1);
            $ret .= $indent;
        } else if (strcmp($page, $subpages)) {
            if ($page==$currentpage){
                $ret .= "<!-- MakeMenu5: page (".$page.") = currentpage (".$currentpage.") -->\n";
                $ret .= sprintf("%s<li class=\"active\"><a href='?p=%s'>%s</a>", $indent, $subpages, $pagenames[$subpages]);
            } else {
                $ret .= "<!-- MakeMenu6: page (".$page.") != currentpage (".$currentpage.") -->\n";
                $ret .= sprintf("%s<li><a href='?p=%s'>%s</a>", $indent, $subpages, $pagenames[$subpages]);
            }
        }
        $ret .= sprintf("</li>\n", $indent);
    }
    $indent = str_repeat(" ", --$level * 2);
    $ret .= sprintf("%s</ul>\n", $indent);
    return($ret);
}
echo MakeMenu($menu, $content);

非常令人费解的输出:

<!-- MakeMenu0: currentpage = overons -->
<!-- MakeMenu0: currentpage = overons -->
<!-- MakeMenu0: currentpage = overons -->
<!-- MakeMenu0: currentpage = overons -->
<!-- MakeMenu2: Level = 0 -->
<ul class="nav navbar-nav">
<!-- MakeMenu5: page (0) = currentpage (overons) -->
  <li class="active"><a href='?p=home'>Home</a></li>
<!-- MakeMenu3: page (overons) = currentpage (overons) -->
  <li class="active dropdowm"><a href='?p=overons'>Over Ons<span class='caret'></span></a>
<!-- MakeMenu1: Level = 2 -->
    <ul class="dropdown-menu">
<!-- MakeMenu5: page (0) = currentpage (overons) -->
      <li class="active"><a href='?p=onsteam'>Ons Team</a></li>
<!-- MakeMenu6: page (1) != currentpage (overons) -->
      <li><a href='?p=organisatie'>Organisatie</a></li>
    </ul>
  </li>
<!-- MakeMenu4: page (diensten) != currentpage (overons) -->
  <li class="dropdown"><a href='?p=diensten'>Diensten<span class='caret'></span></a>
<!-- MakeMenu1: Level = 2 -->
    <ul class="dropdown-menu">
<!-- MakeMenu5: page (0) = currentpage (overons) -->
      <li class="active"><a href='?p=aandeslag'>Aan De Slag</a></li>
<!-- MakeMenu6: page (1) != currentpage (overons) -->
      <li><a href='?p=ictlab'>ICT Lab</a></li>
<!-- MakeMenu6: page (2) != currentpage (overons) -->
      <li><a href='?p=eendagbij'>Een dag bij</a></li>
    </ul>
  </li>
<!-- MakeMenu6: page (1) != currentpage (overons) -->
  <li><a href='?p=opdrachtgevers'>Opdrachtgevers</a></li>
<!-- MakeMenu4: page (verwijzers) != currentpage (overons) -->
  <li class="dropdown"><a href='?p=verwijzers'>Verwijzers<span class='caret'></span></a>
<!-- MakeMenu1: Level = 2 -->
    <ul class="dropdown-menu">
<!-- MakeMenu5: page (0) = currentpage (overons) -->
      <li class="active"><a href='?p=trajectbegeleiding'>Traject begeleiding</a></li>
    </ul>
  </li>
<!-- MakeMenu6: page (2) != currentpage (overons) -->
  <li><a href='?p=contact'>Contact</a></li>
</ul>

1 个答案:

答案 0 :(得分:0)

关于令人费解的行为:

  

让我感到困惑的一件事是$ page的价值如何   通过调试可以告诉您从字符串更改为数字   我已经实施了。

如果仔细观察这一行:

foreach ($menu as $page => $subpages) {

您将看到数组的键被分配给$page。从您的阵列:

$menu = array (
    'home',
    'overons' => array(
        'onsteam',
        'organisatie'
    ),
    'diensten' =>  array(
        'aandeslag',
        'ictlab',
        'eendagbij'
    ),
    'opdrachtgevers',
    'verwijzers' => array(
        'trajectbegeleiding'
    ),
    'contact'
);

我们可以看到有些页面是键,有些是值。这就是为什么有时会有页面名称,有时还有数组索引。

您可以将数组定义为以下内容以防止此行为:

$menu = [
    'home' => null,
    'overons' => [
        'onsteam' => null,
        'organisatie' => null
    ],
    'diensten' =>  [
        'aandeslag' => null,
        'ictlab' => null,
        'eendagbij' => null
    ],
    'opdrachtgevers' => null,
    'verwijzers' => [
        'trajectbegeleiding' => null
    ],
    'contact' => null
];

更进一步,你有一个非常复杂的递归函数。我建议使用PHP Iterators。特别是RecursiveArrayIteratorRecursiveIteratorIterator一起,可以像这样扩展:

class UlRecursiveIteratorIterator extends RecursiveIteratorIterator
{
    public function beginIteration()
    {
        echo '<ul class="nav navbar-nav">', PHP_EOL;    
    }

    public function endIteration()
    {
        echo '</ul>', PHP_EOL;
    }

    public function beginChildren()
    {
        echo str_repeat('    ', $this->getDepth() + 1), '<ul class="dropdown-menu">', PHP_EOL;
    }

    public function endChildren()
    {
        echo str_repeat('    ', $this->getDepth() + 1), '</ul>', PHP_EOL;
        echo str_repeat('    ', $this->getDepth()), '</li>', PHP_EOL;   
    }
}

有了这个迭代器,你的函数可以重构为一个简单的foreach循环:

$iterator = new RecursiveArrayIterator($menu);
$iterator = new UlRecursiveIteratorIterator(
    $iterator,
    RecursiveIteratorIterator::SELF_FIRST
);

foreach ($iterator as $page => $_) {
    $active = false;

    // Used for pritty print only. Remove in production.
    $depth = $iterator->getDepth();
    $line = str_repeat('    ', ($depth + 1) + ($depth === 0 ? 0 : 1));

    if ($page === $content) {
        $active = true;
    }

    $class = $active ? 'active' : '';

    if ($iterator->callHasChildren()) {
        $line .= "<li class=\"$class dropdown\"><a href='?p=$page'>{$pagenames[$page]}<span class='caret'></span></a>";
    } else {
        $line .= "<li class=\"$class\"><a href='?p=$page'>{$pagenames[$page]}</a>";   
    }

    echo $line, PHP_EOL;
}

这是the demo