先贴上代码:
index.php:<?php
include 'include/connect.php';
require 'libs/Smarty.class.php';
$smarty = new Smarty;$sql = "select * from menu where parent_id = 0";
$res = mysql_query($sql);
while($row = mysql_fetch_assoc($res)) {
$pmenu[] = $row;
$subsql = "select * from menu where parent_id = " . $row['id'];
$subres = mysql_query($subsql);
//$subnum = mysql_num_rows($subres);//这个值无法传递给模板
/*在模板处加了一个{if}判断$subnum是否大于0,但由于不可得到$subnum的值而作罢。所有的$subnum都是0
现在的问题是,假如父级菜单没有子菜单,也会显示<ul></ul>,这是我不想有的(本来也不应该有)
如何修正这个问题?*/
while($subrow = mysql_fetch_assoc($subres)) {
$submenu[] = $subrow;
}
}$smarty->assign('pmenu',$pmenu);
$smarty->assign('submenu',$submenu);
//$smarty->assign('subnum',$subnum);$smarty->display('menu.tpl');
menu.tpl:<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>菜单Smarty测试</title>
</head><body>    <div class="menu">
        <ul>
            {section name=p loop=$pmenu}
            <li>{$pmenu[p].name}
                <ul>
                {section name=s loop=$submenu}
                    {if $pmenu[p].id == $submenu[s].parent_id}
                    <li>{$submenu[s].name}</li>
                    {/if}
                {/section}
                </ul>
            </li>
            {/section}
        </ul>
    </div></body>
</html>
数据表结构:CREATE TABLE IF NOT EXISTS menu (
  id tinyint NOT NULL auto_increment,
  parent_id tinyint NOT NULL default '0',
  name varchar(20) NOT NULL,
  PRIMARY KEY (id)
);
如果您 不嫌麻烦,请将上面几个代码保存在相应环境下运行,可以任意录入几个数据到表中测试。我的smarty是在根目录下的libs 。谢谢。
问题:
以上代码可运行并得到正确结果,惟一美中不足的是,假如父级菜单中没有子菜单,也会显示第二级的 <ul></ul> ,我就是想去掉这个没有子菜单的 <ul></ul> 。加上一个 {if} 去判断却得不到 $subnum 的值。请问如何解决?

解决方案 »

  1.   

        <div class="menu">
    {if count($p) gt 0}
            <ul>
                {section name=p loop=$pmenu}
                <li>{$pmenu[p].name}
                    <ul>
                    {section name=s loop=$submenu}
                        {if $pmenu[p].id == $submenu[s].parent_id}
                        <li>{$submenu[s].name}</li>
                        {/if}
                    {/section}
                    </ul>
                </li>
                {/section}
            </ul>
    {/if}
        </div>
      

  2.   

    $sql = "select * from menu where parent_id = 0";
    $res = mysql_query($sql);
    $subnum = mysql_num_rows($subres);
    while($row = mysql_fetch_assoc($res)) {
        $pmenu[] = $row;
        $subsql = "select * from menu where parent_id = " . $row['id'];
        $subres = mysql_query($subsql);    while($subrow = mysql_fetch_assoc($subres)) {
            $submenu[] = $subrow;
        }
    }$smarty->assign('pmenu',$pmenu);
    $smarty->assign('submenu',$submenu);
    $smarty->assign('subnum',$subnum);$smarty->display('menu.tpl');
      

  3.   

    一、{if count($p) gt 0}这个不需要判断吧,这是第一级菜单。那是肯定有数据的二、$subnum = mysql_num_rows($subres);这个放错位置了吧,本来我是有的,注释掉了
      

  4.   


    看错了
    while($row = mysql_fetch_assoc($res)) {
        $pmenu[] = $row;
        $subsql = "select * from menu where parent_id = " . $row['id'];
        $subres = mysql_query($subsql);
        //$subnum = mysql_num_rows($subres);//这个值无法传递给模板你应该将    //$subnum = mysql_num_rows($subres);//这个值无法传递给模板
    的结果保存到数组中,因为你是while所以一直被覆盖,最后只能是最后一次循环的数据了
      

  5.   

       <div class="menu">
            <ul>
                {section name=p loop=$pmenu}
                <li>{$pmenu[p].name}
    {if count($s) gt 0}
                    <ul>
                    {section name=s loop=$submenu}
                        {if $pmenu[p].id == $submenu[s].parent_id}
                        <li>{$submenu[s].name}</li>
                        {/if}
                    {/section}
                    </ul>
    {/if}
                </li>
                {/section}
            </ul>
        </div>
      

  6.   


    哦,应该如此,那这个$subnum怎么存为数组啊
        $s[] = $subnum;
      

  7.   

    while($row = mysql_fetch_assoc($res)) {
        $subsql = "select * from menu where parent_id = " . $row['id'];
        $subres = mysql_query($subsql);
        $row['subnum'] = mysql_num_rows($subres);
        $pmenu[] = $row;
        while($subrow = mysql_fetch_assoc($subres)) {
            $submenu[] = $subrow;
        }
    }用的时候你只需要调用$pmenu下面没组数据中的subnum就行了
      

  8.   

    哭,绕了一个弯,回来还是一样的,没有子菜单的也会出现  <ul></ul> ,中间没有任何 <li></li>
      

  9.   

    好无聊啊, menu.tpl 居然被翻译成这样<?php /* Smarty version 2.6.26, created on 2011-08-10 07:37:29
             compiled from menu.tpl */ ?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>菜单Smarty测试</title>
    </head><body>    <div class="menu">
            <ul>
                <?php unset($this->_sections['p']);
    $this->_sections['p']['name'] = 'p';
    $this->_sections['p']['loop'] = is_array($_loop=$this->_tpl_vars['pmenu']) ? count($_loop) : max(0, (int)$_loop); unset($_loop);
    $this->_sections['p']['show'] = true;
    $this->_sections['p']['max'] = $this->_sections['p']['loop'];
    $this->_sections['p']['step'] = 1;
    $this->_sections['p']['start'] = $this->_sections['p']['step'] > 0 ? 0 : $this->_sections['p']['loop']-1;
    if ($this->_sections['p']['show']) {
        $this->_sections['p']['total'] = $this->_sections['p']['loop'];
        if ($this->_sections['p']['total'] == 0)
            $this->_sections['p']['show'] = false;
    } else
        $this->_sections['p']['total'] = 0;
    if ($this->_sections['p']['show']):            for ($this->_sections['p']['index'] = $this->_sections['p']['start'], $this->_sections['p']['iteration'] = 1;
                     $this->_sections['p']['iteration'] <= $this->_sections['p']['total'];
                     $this->_sections['p']['index'] += $this->_sections['p']['step'], $this->_sections['p']['iteration']++):
    $this->_sections['p']['rownum'] = $this->_sections['p']['iteration'];
    $this->_sections['p']['index_prev'] = $this->_sections['p']['index'] - $this->_sections['p']['step'];
    $this->_sections['p']['index_next'] = $this->_sections['p']['index'] + $this->_sections['p']['step'];
    $this->_sections['p']['first']      = ($this->_sections['p']['iteration'] == 1);
    $this->_sections['p']['last']       = ($this->_sections['p']['iteration'] == $this->_sections['p']['total']);
    ?>
                <li><?php echo $this->_tpl_vars['pmenu'][$this->_sections['p']['index']]['name']; ?>                <ul>
                    <?php unset($this->_sections['s']);
    $this->_sections['s']['name'] = 's';
    $this->_sections['s']['loop'] = is_array($_loop=$this->_tpl_vars['submenu']) ? count($_loop) : max(0, (int)$_loop); unset($_loop);
    $this->_sections['s']['show'] = true;
    $this->_sections['s']['max'] = $this->_sections['s']['loop'];
    $this->_sections['s']['step'] = 1;
    $this->_sections['s']['start'] = $this->_sections['s']['step'] > 0 ? 0 : $this->_sections['s']['loop']-1;
    if ($this->_sections['s']['show']) {
        $this->_sections['s']['total'] = $this->_sections['s']['loop'];
        if ($this->_sections['s']['total'] == 0)
            $this->_sections['s']['show'] = false;
    } else
        $this->_sections['s']['total'] = 0;
    if ($this->_sections['s']['show']):            for ($this->_sections['s']['index'] = $this->_sections['s']['start'], $this->_sections['s']['iteration'] = 1;
                     $this->_sections['s']['iteration'] <= $this->_sections['s']['total'];
                     $this->_sections['s']['index'] += $this->_sections['s']['step'], $this->_sections['s']['iteration']++):
    $this->_sections['s']['rownum'] = $this->_sections['s']['iteration'];
    $this->_sections['s']['index_prev'] = $this->_sections['s']['index'] - $this->_sections['s']['step'];
    $this->_sections['s']['index_next'] = $this->_sections['s']['index'] + $this->_sections['s']['step'];
    $this->_sections['s']['first']      = ($this->_sections['s']['iteration'] == 1);
    $this->_sections['s']['last']       = ($this->_sections['s']['iteration'] == $this->_sections['s']['total']);
    ?>
                        <?php if ($this->_tpl_vars['pmenu'][$this->_sections['p']['index']]['id'] == $this->_tpl_vars['submenu'][$this->_sections['s']['index']]['parent_id']): ?>
                        <li><?php echo $this->_tpl_vars['submenu'][$this->_sections['s']['index']]['name']; ?>
    </li>
                        <?php endif; ?>
                    <?php endfor; endif; ?>
                    </ul>
                </li>
                <?php endfor; endif; ?>
            </ul>
        </div></body>
    </html>
      

  10.   

    其实我是不用 smarty 的,临时下了个观察一下。
    本想从他生成的 php 代码中 看看有什么可利用的地方。
    但没想到他生成的代码是那么的“烂”,可能与你的模板有关系你的内层循环是需要遍历整个第二级数据的,这显然是不妥当的
    我以为取数的代码应写作这样
    while($row = mysql_fetch_assoc($res)) {
        $subsql = "select * from menu where parent_id = " . $row['id'];
        $subres = mysql_query($subsql);
        $subnum = mysql_num_rows($subres);//这个值无法传递给模板
        while($subrow = mysql_fetch_assoc($subres)) {
            $submenu[] = $subrow;
        }
        $row['child'] = $submenu;
        $row['count'] = $subnum;
        $pmenu[] = $row;
    }
    模板部分写成这样    <div class="menu">
            <ul>
                {section name=p loop=$pmenu}
                <li>{$pmenu[p].name}
                  {if if $pmenu[p].count > 0}
                    <ul>
                    {section name=s loop=$pmenu[p].child}
                        <li>{$pmenu[p].child[s].name}</li>
                    {/section}
                    </ul>
                  {/if}
                </li>
                {/section}
            </ul>
        </div>比较妥当,但不知是否符合 smarty 的语法
      

  11.   

    $query_class=mysql_query("select * from p_newsclass where f_id=0 order by id DESC");
    while($row_class=mysql_fetch_array($query_class)){
    $arr_class[]=array("name"=>$row_class[name],"id"=>$row_class[id]);
    $query_class_tow=mysql_query("select * from p_newsclass where f_id=$row_class[id]");
    while($row_class_tow=mysql_fetch_array($query_class_tow)){
         $arr_class_tow[]=array("name"=>$row_class_tow[name],"f_id"=>$row_class_tow[f_id]);
         $smarty->assign("arr_class_tow",$arr_class_tow);//二级导航
    }
    }
    $smarty->assign("arr_class",$arr_class);//一级导航
      

  12.   

    <div id="menu">
    <ul>
    <li><a href="login.php">首页</a></li>
    {section name=class loop=$arr_class}
    <li><a href="list.php?id={$arr_class[class].id}">{$arr_class[class].name}</a>
    <ul>
    {section name=class_tow loop=$arr_class_tow}
    {if $arr_class_tow[class_tow].f_id==$arr_class[class].id}
    <li><a href="list.php?id={$arr_class_tow[class_tow].id}">{$arr_class_tow[class_tow].name}</a></li>
    {/if}
    {/section}
    </ul>
    </li>
    {/section}
    </ul>
    </div>
      

  13.   

    $query_class=mysql_query("select * from p_newsclass where f_id=0 order by id DESC");
    while($row_class=mysql_fetch_array($query_class)){
    $arr_class[]=array("name"=>$row_class[name],"id"=>$row_class[id]);
    $query_class_tow=mysql_query("select * from p_newsclass where f_id=$row_class[id]");
    while($row_class_tow=mysql_fetch_array($query_class_tow)){
         $arr_class_tow[]=array("name"=>$row_class_tow[name],"f_id"=>$row_class_tow[f_id]);
         $smarty->assign("arr_class_tow",$arr_class_tow);//二级导航
    }
    }
    $smarty->assign("arr_class",$arr_class);//一级导航