分享一个php实现无限级分类程序代码
无限级分类是所有程序开发中会碰到的一个问题,下面我来介绍php+mysql实现的一个无限级分类程序,有需要的朋友可参考参考,下面给大家看看我的数据库结构吧,数据库的名字为 fa_category
Field Type Comment
cid int(11) 分类id
catename varchar(255) 分类名字
catetype int(1) 分类类型,1为单页面,2为普通分类
catdir varchar(255) 英文目录
display int(1) 1为显示,2为不显示
keywords varchar(255) 栏目关键字
description text 栏目描述
ctime int(11) 创建时间
我们使用一个parentid字段来记录父节点的id,如果parentid为0,则为root,不多说,我们看看代码怎么写吧,我们要实现的功能就是如图片所示:
怎么样把它这样显示呢?这个问题我想了很久,先看看这段SQL语句吧,代码如下:
SELECT c.cat_id, c.cat_name, c.measure_unit, c.parent_id, c.is_show, c.show_in_nav, c.grade ,c.sort_order, COUNT ( s.cat_id ) AS has_children
FROM ecs_category AS c
LEFT JOIN ecs_category AS s ON s.parent_id = c.cat_id
GROUP BY c.cat_id
ORDER BY c.parent_id, c.sort_order ASC
用左连接连接一个表,返回一个字段 has_children,这个字段是记录有多少子节点,看看代码吧:
public function getCategory( $catid =0, $re_type = true, $selected =0)
{
$db = new Public_DataBase();
$sql = 'select c.cid,c.catename,c.catetype,c.ctime,c.parentid,count(s.cid) as has_children from ' .
__MYSQL_PRE. 'category as c left join ' .
__MYSQL_PRE. 'category as s on s.parentid=c.cid group by c.cid order by c.parentid asc' ;
$res = $db ->selectTable( $sql );
$cateInfo = self::getChildTree( $catid , $res );
if ( $re_type ==true)
{
$select = '' ;
foreach ( $cateInfo as $val )
{
$select .= '<option value="' . $val [ 'cid' ] . '" ' ;
$select .= ( $selected == $val [ 'cid' ]) ? "selected='ture'" : '' ;
$select .= '>' ;
if ( $val [ 'level' ]>0)
{
$select .= str_repeat ( ' ' , $val [ 'level' ] * 4);
}
$select .= htmlspecialchars( addslashes ( $val [ 'catename' ]), ENT_QUOTES) . '</option>' ;
}
return $select ;
}
else
{
foreach ( $cateInfo as $key => $val )
{
if ( $val [ 'level' ]>0)
{
$cateInfo [ $key ][ 'catename' ] = "|" . str_repeat ( ' ' , $val [ 'level' ] * 8). "└─" . $val [ 'catename' ];
}
}
return $cateInfo ;
}
}
/**
* 通过父ID递归得到所有子节点树
* @param int $catid 上级分类
* @param array $arr 含有所有分类的数组
* @return array
*/
public function getChildTree( $catid , $arr )
{
$level = $last_cat_id = 0;
while (! empty empty ( $arr ))
{
foreach ( $arr as $key => $value )
{
$cid = $value [ 'cid' ];
if ( $level == 0 && $last_cat_id == 0)
{
if ( $value [ 'parentid' ] > 0)
{
break ;
}
$options [ $cid ] = $value ;
$options [ $cid ][ 'level' ] = $level ;
$options [ $cid ][ 'id' ] = $cid ;
$options [ $cid ][ 'name' ] = $value [ 'catename' ];
unset( $arr [ $key ]);
if ( $value [ 'has_children' ] == 0)
{
continue ;
}
$last_cat_id = $cid ;
$cat_id_array = array ( $cid );
$level_array [ $last_cat_id ] = ++ $level ;
continue ;
}
if ( $value [ 'parentid' ] == $last_cat_id )
{
$options [ $cid ] = $value ;
$options [ $cid ][ 'level' ] = $level ;
$options [ $cid ][ 'id' ] = $cid ;
$options [ $cid ][ 'name' ] = $value [ 'catename' ];
unset( $arr [ $key ]);
if ( $value [ 'has_children' ] > 0)
{
if ( end ( $cat_id_array ) != $last_cat_id )
{
$cat_id_array [] = $last_cat_id ;
}
$last_cat_id = $cid ;
$cat_id_array [] = $cid ;
$level_array [ $last_cat_id ] = ++ $level ;
}
}
elseif ( $value [ 'parentid' ] > $last_cat_id )
{
break ;
}
}
$count = count ( $cat_id_array );
if ( $count > 1)
{
$last_cat_id = array_pop ( $cat_id_array );
}
elseif ( $count == 1)
{
if ( $last_cat_id != end ( $cat_id_array ))
{
$last_cat_id = end ( $cat_id_array );
}
else
{
$level = 0;
$last_cat_id = 0;
$cat_id_array = array ();
continue ;
}
}
if ( $last_cat_id && isset( $level_array [ $last_cat_id ]))
{
$level = $level_array [ $last_cat_id ];
}
else
{
$level = 0;
}
}
return $options ;
}
用smarty的一个循环就可以把它显示出来,效果和上面图片的一样!大家有什么问题可以给我留言。