PHP无限分类实例程序
无限分类的原理:就像windows下新建一个文件夹,在新建的文件夹下又可以新建一个文件夹,这样无限循环下去,无限分类也是这样,父类可以分出它子类,子类又可以分出它的子类,这样一直无限循环下去.
例1,代码如下:
$yArr = array ( 1 => array ( 'id' => '1' , 'parentid' =>0, 'name' => '一级栏目一' ), 2 => array ( 'id' => '2' , 'parentid' =>0, 'name' => '一级栏目二' ), 3 => array ( 'id' => '3' , 'parentid' =>1, 'name' => '二级栏目一' ), 4 => array ( 'id' => '4' , 'parentid' =>1, 'name' => '二级栏目二' ), 5 => array ( 'id' => '5' , 'parentid' =>2, 'name' => '二级栏目三' ), 6 => array ( 'id' => '6' , 'parentid' =>3, 'name' => '三级栏目一' ), 7 => array ( 'id' => '7' , 'parentid' =>3, 'name' => '三级栏目二' ), 8 => array ( 'id' => '8' , 'parentid' =>2, 'name' => '二级栏目三' ), ); /** * 获取当前id的子ID * @param array $data 原始数组 * @param int $id 当前id * @param int $layer 当前层级 */ function genCate( $data , $pid = 0, $level = 0) { if ( $level == 10) break ; $l = str_repeat ( " " , $level ); $l = $l . '└' ; static $arrcat = array (); $arrcat = empty empty ( $level ) ? array () : $arrcat ; foreach ( $data as $k => $row ) { /** * 如果父ID为当前传入的id */ if ( $row [ 'parentid' ] == $pid ) { //如果当前遍历的id不为空 $row [ 'name' ] = $l . $row [ 'name' ]; $row [ 'level' ] = $level ; $arrcat [] = $row ; //var_array($arr); genCate( $data , $psiff , $row [ 'id' ], $level +1); //递归调用 } //开源代码phpfensi.com } return $arrcat ; } $carr = genCate( $yArr ); echo "<select>" ; foreach ( $carr as $row ) { echo "<option value={$row['id']}>" ; echo $row [ 'name' ]; echo "</option>" ; } echo "</select>" ;注:因为是无限次的调用,所以我加了个判断,在层级$level=10的时候让他跳出,没有哪个正常网站会放超过10层的目录结构吧.
执行到static变量后,判断下当前层级,如果层级为0,那么表示这是最高级菜单,需要清空$arrcate的数据重新声明.
例2,代码如下:
//我们建一个表 "class" CREATE TABLE `class` ( `id` int (11) NOT NULL auto_increment COMMENT '分类id' , `f_id` int (11) NOT NULL COMMENT '父id' , ` name ` varchar (25) collate gbk_bin NOT NULL COMMENT '分类名称' , PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=gbk COLLATE =gbk_bin AUTO_INCREMENT=1 ;代码如下:
<?php header( "Content-type:text/html;charset=utf-8" ); $db = new mysqli( "localhost" , "root" , "" , "news_php100" ) ; //实例化一个数据库连接。使用这个前一定要确保已经加载了mysqli类库, 或者用mysql_connect这个方式连接。 if (mysqli_connect_errno()){ echo "链接失败:" .mysqli_connect_error(); exit (); } $db ->query( "set names utf8" ); $result = $db ->query( "select name from class where f_id=0" ); //查找f_id=0的分类,也就是查找每一个大类。 while ( $row = $result ->fetch_assoc()){ echo $row [ 'name' ]. "< br>" ; //这样就把每个大类循环出来了。 } //同样我们可以把新闻的子类循环出来。 $result = $db ->query( "select * from class where f_id=1" ); //查找f_id=1的分类,也就是查找‘新闻’的子类。 while ( $row = $result ->fetch_assoc()){ echo $row [ 'name' ]." "; //这样就把‘新闻’的子类循环出来了。注意:只是子类,不包括孙子类。 } //写到这里,我们会发现一个问题,如果这个分类是10级分类,难道我们要写 10个循环把它每个子类循环出来?如果是更多级分类呢,这样写显然是不现实的。 //那又有什么办法解决呢?我们可以写一个递归的函数,把f_id作为参数传入, 不断循环每一个f_id的值,也就是说把每一个f_id值的子类循环出来。 //首先我们把各个分类的值保存在一个二维数组中,在下面的递归函数里有用。 $result = $db ->query( "select * from class" ); while ( $row = $result ->fetch_assoc()){ $arr []= array ( $row [id], $row [f_id], $row [name]); //每一行保存一个 分类的id,f_id,name的信息。 } function fenlei( $f_id =0){ //$f_id初始化为0,也就是从最大分类开始循环. global $arr ; //声明$arr为全局变量才可在函数里引用。 for ( $i =0; $i < count ( $arr ); $i ++){ //对每个分类进行循环。 if ( $arr [ $i ][1]== $f_id ){ //$arr[$i][1]表示第$i+1个分类的f_id的值。 开始 $f_id =0,也就是把f_id=0的分类输出来。 echo $arr [ $i ][2]. "< br>" ; //$arr[$i][1]表示第$i+1个分类的name的值。 fenlei( $arr [ $i ][0]); //$arr[$i][1]表示第$i+1个分类的id的值。进行递归 ,也就是把自己的id作为f_id参数把自己的子类再循环出来。 } } } fenlei(); //使用这个函数. ?>例3,php无限分类,支持输出树状图,代码如下:
<?php /** * 通用的树型类,可以生成任何树型结构 */ class tree { /** * 生成树型结构所需要的2维数组 * @var array */ var $arr = array (); /** * 生成树型结构所需修饰符号,可以换成图片 * @var array */ var $icon = array ( '│' , '├' , '└' ); /** * @access private */ var $ret = '' ; /** * 构造函数,初始化类 * @param array 2维数组,例如: * array( * 1 => array('id'=>'1','parentid'=>0,'name'=>'一级栏目一'), * 2 => array('id'=>'2','parentid'=>0,'name'=>'一级栏目二'), * 3 => array('id'=>'3','parentid'=>1,'name'=>'二级栏目一'), * 4 => array('id'=>'4','parentid'=>1,'name'=>'二级栏目二'), * 5 => array('id'=>'5','parentid'=>2,'name'=>'二级栏目三'), * 6 => array('id'=>'6','parentid'=>3,'name'=>'三级栏目一'), * 7 => array('id'=>'7','parentid'=>3,'name'=>'三级栏目二') * ) */ function tree( $arr = array ()) { $this ->arr = $arr ; $this ->ret = '' ; return is_array ( $arr ); } /** * 得到父级数组 * @param int * @return array */ function get_parent( $myid ) { $newarr = array (); if (!isset( $this ->arr[ $myid ])) return false; $pid = $this ->arr[ $myid ][ 'parentid' ]; $pid = $this ->arr[ $pid ][ 'parentid' ]; if ( is_array ( $this ->arr)) { foreach ( $this ->arr as $id => $a ) { if ( $a [ 'parentid' ] == $pid ) $newarr [ $id ] = $a ; } } return $newarr ; } /** * 得到子级数组 * @param int * @return array */ function get_child( $myid ) { $a = $newarr = array (); if ( is_array ( $this ->arr)) { foreach ( $this ->arr as $id => $a ) { if ( $a [ 'parentid' ] == $myid ) $newarr [ $id ] = $a ; } } return $newarr ? $newarr : false; } /** * 得到当前位置数组 * @param int * @return array */ function get_pos( $myid ,& $newarr ) { $a = array (); if (!isset( $this ->arr[ $myid ])) return false; $newarr [] = $this ->arr[ $myid ]; $pid = $this ->arr[ $myid ][ 'parentid' ]; if (isset( $this ->arr[ $pid ])) { $this ->get_pos( $pid , $newarr ); } if ( is_array ( $newarr )) { krsort( $newarr ); foreach ( $newarr as $v ) { $a [ $v [ 'id' ]] = $v ; } } return $a ; } /** * ------------------------------------- * 得到树型结构 * ------------------------------------- * @author Midnight(杨云洲), yangyunzhou@foxmail.com * @param $myid 表示获得这个ID下的所有子级 * @param $str 生成树形结构基本代码, 例如: "<option value=$id $select>$spacer$name</option>" * @param $sid 被选中的ID, 比如在做树形下拉框的时候需要用到 * @param $adds * @param $str_group * @return unknown_type */ function get_tree( $myid , $str , $sid = 0, $adds = '' , $str_group = '' ) { $number =1; $child = $this ->get_child( $myid ); if ( is_array ( $child )) { $total = count ( $child ); foreach ( $child as $id => $a ) { $j = $k = '' ; if ( $number == $total ) { $j .= $this ->icon[2]; } else { $j .= $this ->icon[1]; $k = $adds ? $this ->icon[0] : '' ; } $spacer = $adds ? $adds . $j : '' ; $selected = $id == $sid ? 'selected' : '' ; @extract( $a ); $parentid == 0 && $str_group ? eval ( "$nstr = " $str_group ";" ) : eval ( "$nstr = " $str ";" ); $this ->ret .= $nstr ; $this ->get_tree( $id , $str , $sid , $adds . $k . ' ' , $str_group ); $number ++; } } return $this ->ret; } /** * 同上一方法类似,但允许多选 */ function get_tree_multi( $myid , $str , $sid = 0, $adds = '' ) { $number =1; $child = $this ->get_child( $myid ); if ( is_array ( $child )) { $total = count ( $child ); foreach ( $child as $id => $a ) { $j = $k = '' ; if ( $number == $total ) { $j .= $this ->icon[2]; } else { $j .= $this ->icon[1]; $k = $adds ? $this ->icon[0] : '' ; } $spacer = $adds ? $adds . $j : '' ; $selected = $this ->have( $sid , $id ) ? 'selected' : '' ; //echo $sid.'=>'.$id.' : '.$selected.' . <br/>'; @extract( $a ); eval ( "$nstr = " $str ";" ); $this ->ret .= $nstr ; $this ->get_tree_multi( $id , $str , $sid , $adds . $k . ' ' ); $number ++; } } return $this ->ret; } function have( $list , $item ){ return ( strpos ( ',,' . $list . ',' , ',' . $item . ',' )); } } ?>注: 无平台限制,只需要告知id,parentid,name 即可,上面总结了三种无限分类代码都没有平台限制,不过只能使用在php中,我们只要搞清楚id,parentid,name三者的关系即可.
查看更多关于PHP无限分类实例程序 - php高级应用的详细内容...
声明:本文来自网络,不代表【好得很程序员自学网】立场,转载请注明出处:http://www.haodehen.cn/did30299