【问题标题】:CSS Dropdown menu through PHP, logic defeats me通过PHP的CSS下拉菜单,逻辑打败了我
【发布时间】:2025-12-28 11:55:16
【问题描述】:

今天早上我的大脑似乎不想工作..我有以下数组:

private $nav_pages = [['0', 'Home', 'home'],
                      ['0', 'About Us', 'about'],
                      ['0', 'Our Services', 'services'],
                      ['1', 'PROCURE TO PAY (P2P)', 'procure'],
                      ['1', 'ORDER TO CASH (02C)', 'cash'],
                      ['1', 'GENERAL ACCOUNTING', 'general'],
                      ['2', 'Charting of Accounts', 'charting'],
                      ['2', 'General Ledger Maintenance', 'maintenance'],
                      ['2', 'Accounts Receivable Services', 'receivable'],
                      ['2', 'Accounts Payable Services', 'payable'],
                      ['2', 'Reconciliation of Bank Accounts and Credit Cards', 'reconciliation'],
                      ['2', 'Preparing Financial Statements', 'statements'],
                      ['2', 'Payroll Processing', 'payroll'],
                      ['1', 'CLOSING & REPORTING', 'closing'],
                      ['0', 'How It Works', 'how-it-works'],
                      ['0', 'Contact Us','contact'],
                      ['0', 'Careers', 'careers']];

然后将其馈送到一个 php 页面,该页面旨在布置一个多层纯 css 下拉菜单.. php 页面代码是:

<ul class="<?php echo $ul_class; ?>">

<?php $this_layer = 0;

// place array content into variables
foreach ($links as $link) {

    $item_layer  = $link[0];
    $item_string = $link[1];
    $item_link   = $link[2];

    if ($item_layer > $this_layer) { ?>
        <ul>
    <?php $this_layer++; }
    elseif ($item_layer == $this_layer) { ?>
        <li class="<?php echo $item_link; ?>">
            <a class="<?php echo $item_link; ?>"
               href="/<?php echo $item_link; ?>">
                <?php echo $item_string; ?>
            </a>
        </li>
    <?php }
    elseif ($item_layer < $this_layer) { ?>
        </li></ul>
    <?php $this_layer--; } ?>
<?php } ?>

输出不正确,因为上面的代码总是在第二层准备好关闭之前关闭包含第二层的列表项。如果这有意义..

<ul class="pages_nav">
<li class="home">
    <a class="home"
       href="/home">
        Home                
    </a>
</li>
<li class="about">
    <a class="about"
       href="/about">
        About Us                
    </a>
</li>
<li class="services">
    <a class="services"
       href="/services">
        Our Services                
    </a>
</li>
<ul>
    <li class="cash">
        <a class="cash"
           href="/cash">
            ORDER TO CASH (02C)                
        </a>
    </li>
    <li class="general">
        <a class="general"
           href="/general">
            GENERAL ACCOUNTING                
        </a>
    </li>
    <ul>
        <li class="maintenance">
            <a class="maintenance"
               href="/maintenance">
                General Ledger Maintenance                
            </a>
        </li>
        <li class="receivable">
            <a class="receivable"
               href="/receivable">
                Accounts Receivable Services                
            </a>
        </li>
        <li class="payable">
            <a class="payable"
               href="/payable">
                Accounts Payable Services                
            </a>
        </li>
        <li class="reconciliation">
            <a class="reconciliation"
               href="/reconciliation">
                Reconciliation of Bank Accounts and Credit Cards                
            </a>
        </li>
        <li class="statements">
            <a class="statements"
               href="/statements">
                Preparing Financial Statements               
            </a>
        </li>
        <li class="payroll">
            <a class="payroll"
               href="/payroll">
                Payroll Processing                
            </a>
        </li>
        </li></ul>
    </li></ul>
<li class="contact">
    <a class="contact"
       href="/contact">
        Contact Us                
    </a>
</li>
<li class="careers">
    <a class="careers"
       href="/careers">
        Careers                
    </a>
</li>

解决方案:

<ul class="<?php echo $ul_class; ?>">

<?php $this_layer = 0;

// place array content into variables
foreach ($links as $link) {

    $item_layer  = $link[0];
    $item_string = $link[1];
    $item_link   = $link[2];

    // check if link needs to be manipulated
    switch($do) {
        case 'strtolower':
            $item_string = strtolower($item_string);
            break;
        case 'strtoupper':
            $item_string = strtoupper($item_string);
            break;
    } ?>

    <?php if ($item_layer > $this_layer) { ?>
        <ul>
        <li class="<?php echo $item_link; ?>">
            <a class="<?php echo $item_link; ?>"
               href="/<?php echo $item_link; ?>">
                <?php echo $item_string; ?>
            </a>
    <?php $this_layer++; }
    elseif ($item_layer == $this_layer) { ?>
        </li><li class="<?php echo $item_link; ?>">
            <a class="<?php echo $item_link; ?>"
               href="/<?php echo $item_link; ?>">
                <?php echo $item_string; ?>
            </a>
    <?php }
    elseif ($item_layer < $this_layer) { ?>
        </li></ul></li><li class="<?php echo $item_link; ?>">
        <a class="<?php echo $item_link; ?>"
           href="/<?php echo $item_link; ?>">
            <?php echo $item_string; ?>
        </a>
        <?php $this_layer--; } ?>
<?php } ?>

【问题讨论】:

  • 你不应该喜欢:
    • 主要项目
      • 子项目
  • 没错!但我无法理解 forelse 循环的逻辑来做到这一点......就像我说的......今天早上我的头不工作......
  • 让我来回答你秒
  • 我怎样才能显示第一个项目?如果级别更高,您不会回显 li,您的 html 仍然会显示项目。我有那么瞎吗?

标签: php html arrays drop-down-menu


【解决方案1】:

永远不要关闭li标签,添加东西时关闭它

foreach ($links as $link) {
    if ($item_layer > $this_layer) { 
        echo '<ul><li> ......';
        this_layer++; 
    }elseif ($item_layer == $this_layer) {
        echo '</li><li>......';
    }elseif ($item_layer < $this_layer) {
        echo '</li></ul><li>......';
        $this_layer--; 
    }
}

最后你可能需要在 foreach 之外添加一个echo '&lt;/li&gt;&lt;/ul&gt;' 以关闭所有内容

【讨论】:

    【解决方案2】:

    不得不对代码进行一些修改,通常我将 php 菜单结构组织成树形结构,这样更容易解析成 html 菜单,但这里是:

    <ul class="<?php echo $ul_class; ?>">
    <?php 
    $this_layer = 0;
    $closeit = false;
    // place array content into variables
    foreach ($nav_pages as $link) {
        $item_layer  = $link[0];
        $item_string = $link[1];
        $item_link   = $link[2];
    
        if ($item_layer > $this_layer) { 
          // Changing level, dont close the previous li
          ?><ul><?php 
          $closeit = false;
          $this_layer++; 
        }
        if ($item_layer == $this_layer) { 
          // Same level, check if you need to close previous li
          if ($closeit) {
            ?></li><?php
          }
          // Render the li
        ?>
      <li class="<?php echo $item_link; ?>">
        <a class="<?php echo $item_link; ?>"
            href="/<?php echo $item_link; ?>">
          <?php echo $item_string; ?>
        </a>
        <?php 
          // Close it on next loop
          $closeit = true;
        }
        elseif ($item_layer < $this_layer) { 
          // Changing layer back down, close the previous li and the current level ul
          ?>
      </li>
    </ul>
        <?php
          $this_layer--; 
        } 
    } 
    // Finished loop, there should still be a li waiting to be closed
    if ($closeit) { 
      ?></li><?php 
    }
    // Close menu
    ?>
    </ul>
    

    应该可以了,如果不行请告诉我

    建议的php菜单结构:

    $menu = array(
        array(
            "url"=>"/place.php",
            "text"=>"Go to place"
        ),
        array(
            "url"=>"/place2.php", // not necessary
            "text"=>"with submenu",
            "children"=>array(
                array(
                    "url"=>"/placewithinplace2.php",
                    "text"=>"submenu item"
                )
            )
        )
    );
    

    【讨论】:

    • nope.. 这并不能解决在关联子菜单到位之前关闭列表项的问题。
    • 编辑了帖子,之前的回答没有解决问题。
    • 不。对不起.. ul 没有关闭.. 但让我看看你的代码。我通过添加一个要关闭的变量来确定是否关闭(最初希望避免这种情况)来了解您所得到的结果。
    • 奇怪,我用你的菜单数组测试了它,它呈现了有效的 html。你确定uls没有关闭吗?工资单处理链接后应该有一个 。以递归方式构建这些菜单要容易得多,但如果将菜单数组构建为树,则更容易。 (我的结果:pastebin.com/xipQSbJh
    • 带有建议菜单结构的已编辑答案,具有更易于阅读的优点,允许将新属性添加到菜单项而不影响现有代码,并且可以创建递归函数以使其变得非常容易.