如果要对数据库进行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
?>