如果要对数据库进行N*N次的查询才能取出多级类别的树,这是个糟糕的解决办法。
梅花雪的解决办法是一次取出,多次利用。我受到启发。他在客户端完成这个操作。然而字符串是在服务器端生成的。
我的做法是在服务器端将数据分两次从库里取出,用两个交叉索引的数组来存放对象。然后对这两个数组进行正则查询的操作,分级找出,生成类别菜单字符串
数据表和css还有图片我都打包了。
<?php//$q = "select CONCAT_WS( '_', id , pid) as indexKey , CONCAT_WS('_' , title , link , published , ordering , access , params ) as valueKey from #__collector_menu where access>=0 ";
/*** 共计查找数据库两次,使用CONCAT_WS函数两次* 使用正则搜数组一次(N条记录)*N次(N*X条记录)*(N*X)次(Y条记录,依次类推)。* 对于2级类,则是 2数据库+1*N次正则。* 如果用数据库,则是1数据库 * N次数据库。* 如果用数组遍历,则是1数据库(Y条记录)+N*Y+(Y-N)次数组循环。** 不知道哪个效率更高。*/
$q = "select CONCAT_WS( '_', id , pid) as indexKey , id , pid , title , link , published , ordering , access , params from #__collector_menu where access>=0 ";$database->setQuery($q);$rowsIndex = $database->loadResultArray(0,'id','indexKey'); //prt($rowsIndex);$rows = $database->loadAssocList( 'indexKey'); //prt($rows);
/* 搜出所有的顶级类别 */$reg = "#([0-9]+)_0#i";$mainIndex=preg_grep($reg,$rowsIndex); //prt($mainIndex);
/* 为每一个顶级类别找出其子类别 */foreach ($mainIndex as $mkey=>$vk) { /* 取出模版 */ $mainItem = MainItemTpl(); $mainItem = str_replace('{topTitle}',$rows[$vk]['title'],$mainItem); $sub='';
/* 在索引数组里找出下级类别 */ $reg = "#([0-9]+)_".$mkey."#i"; $subIndex=preg_grep($reg,$rowsIndex); //prt($subIndex);
/* 如果找到 */ if(count($subIndex)){ /* 组合子菜单 */ $sub ='<table width="100%" border="0" cellspacing="0" cellpadding="0" bgcolor="#F4FBF4">'."/n"; foreach ($subIndex as $subKey=>$subV) { //echo $subKey."=".$subV."<br/>";//prt($rows[$subV]); /* 组合子菜单 */
$sub .="<tr>/n"; $sub .='<td width="17%" align="center" class="tdline"><img src="img/newitem.gif" width="7" height="10"/></td>'; $sub .='<td width="83%" class="tdline"><a href="'.$rows[$subV][link].'" >'.$rows[$subV]['title']."</a></td>/n"; $sub .="</tr>";
}//遍历字项结束 $sub .="</table>/n"; }//end if $mainItem = str_replace('{sub}',$sub,$mainItem); echo $mainItem;}
function MainItemTpl(){
$mainTpl = <<<EOD
<!-- mainItem --><table width="120" border="0" align="center" cellpadding="0" cellspacing="0"> <tr> <td width="19" height="24" align="center" background="img/newlinebg2.gif"><img src="img/topitem2.gif" width="11" height="13" border="0" onClick="showHide(this)" class="topitem"/></td> <td width="101" background="img/newlinebg2.gif" class="topitem" onClick="showHide(this)">{topTitle}</td> </tr> <tr> <td colspan="2" align="center"> {sub} </td> </tr></table><!-- /mainItem -->
EOD;return $mainTpl;
}//end func
?>