根据parent_id递归的无限分类和下拉菜单。
先说下,这个对小树来讲还是很快的,大树没有测试,呵呵,递归对大树没什么优势。数据库设计
id, title, parent_id, last
MODEL:
先来个正常全部列表哦:
function get_list()
{
$query = $this->db->get('catalog');
return $query->result_array();
}
在看一个根据parent_id自动生成的多维数组:
function get_tree($parent_id = null)
{
$this->db->where('parent_id',$parent_id);
$this->db->select('id,parent_id,last,title_english');
$query = $this->db->get('catalog');
$list['son'] = $query->result_array();
foreach ($list['son'] as &$row) {
if(array_key_exists('last',$row))
{
if(!$row['last'])
{
$temp = $this->get_tree($row['id']);//这里用了个递归
$row['son'] = $temp['son'];
}
}
}
return $list;
}
下一个是生成视图的下拉列表或者多级的菜单:
function read_tree($tree,$display = array(
'str_out'=>array('open'=>"<ul>\n",'close'=>"</ul>\n"),
'str_in'=> array('open'=>"<li>",'close'=>"</li>\n"),
'blank'=>array('many'=>0,'what'=>' ','increase'=>0),
'attr'=>array('value'=>'id'),
'with_last' => true)
)
{
$str = "";
$str .= $display['str_out']['open'];
foreach ($tree['son'] as $t)
{
if(array_key_exists('last',$t))
{
$show = true;
if($t['last']){if(!$display['with_last']){$show = false;}}
if($show){
$str .= $display['str_in']['open'];
if($display['attr'] != array())
{
$str = substr($str,0,strlen($str)-1);
foreach ($display['attr'] as $k=>$v)
{
$str .= ' '.$k.'="'.$t[$v].'"';
}
$str .= '>';
}
for($i=0;$i<$display['blank']['many'];$i++)
{
$str .= $display['blank']['what'];
}
$str .= $t['title_english'].$display['str_in']['close'];
}
}
if(array_key_exists('son',$t))
{
// print_r($display);
$str .= $this->read_tree(
$t,
array('str_out'=>$display['str_out'],
'str_in'=>$display['str_in'],
'blank'=>array(
'many'=>($display['blank']['many']+$display['blank']['increase']),
'what'=>$display['blank']['what'],
'increase'=>$display['blank']['increase']
),
'attr' => $display['attr'],
'with_last'=>$display['with_last'],
)
);
}
}
$str .= $display['str_out']['close'];
return $str;
}
控制器里调用:
$tree = $this->catalog_model->get_tree();
echo '<select>';
echo $this->catalog_model->read_tree($tree,array('str_out'=>array('open'=>'','close'=>''),'str_in'=>array('open'=>'<option>','close'=>'</option>'),'blank'=>array('increase'=>1,'what'=>' ','many'=>0),'attr'=>array('value'=>'id'),'with_last'=>false));
echo '</select>';
大家把echo的东西换成变量传递到视图里就可以啦。
参数设置的有点多,但是还是很好用D。
嘿嘿。数据结构学的不好,搞了半个下午。
希望能帮助更多的人。 兄弟,将实例打个包吧。。 我最担心的就是每次递归就要查一遍数据库,当数据库有1万条数据,你的栏目有50个,那就相当于要递归50次(就是循环50次),查询50次数据库,总数就要查询50万行得出结果。如果是多人cms系统,这种查询方法就很吓人了。
我认为最好的方法是把符合要求的 50条数据先查出来放在一个数组里。然后对数组进行递归或者别的什么方法进行计算。
就和楼主说的,只能使用小树。
有没有高人指点一下大树的递归啊 本帖最后由 pk4321 于 2009-10-27 17:30 编辑
ptCID ptPID ptName ptRank
1 0 A 0001
3 1 A1 00010001
6 3 A11 000100010001
5 1 A2 00010002
4 1 A3 00010003
2 0 B 0002
至少加个类似上面的最后一列,就完全避免了递归了,但就是添加、移动、删除结点的需要额外的维护!
这样一来,这个树的每个子树最多可以有9999个结点,而整个树的深度 varchar(200) 就有50级!
CI应该增加一个用以上模式的树的一个library 分类当然要做成缓存文件,考虑性能的话
页:
[1]