【问题标题】:php: Generate dynamic menu with CSS code from multidimensional arrayphp:使用多维数组中的 CSS 代码生成动态菜单
【发布时间】:2018-07-16 09:49:54
【问题描述】:

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

真正让我感到困惑的一件事是 $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>

【问题讨论】:

    标签: php html css arrays multidimensional-array


    【解决方案1】:

    关于令人费解的行为:

    真正让我困惑的一件事是 $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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-29
      • 1970-01-01
      • 2011-02-17
      • 2023-03-11
      • 2011-04-02
      • 2013-08-07
      相关资源
      最近更新 更多