好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

PHP无限分类实例程序 - php高级应用

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 ( "&nbsp;&nbsp;&nbsp;&nbsp;" ,  $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 . '&nbsp;' , $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 . '&nbsp;' );       $number ++;     }    }     return   $this ->ret;   }      function  have( $list , $item ){     return ( strpos ( ',,' . $list . ',' , ',' . $item . ',' ));   }  }  ?> 

注: 无平台限制,只需要告知id,parentid,name 即可,上面总结了三种无限分类代码都没有平台限制,不过只能使用在php中,我们只要搞清楚id,parentid,name三者的关系即可.

查看更多关于PHP无限分类实例程序 - php高级应用的详细内容...

  阅读:43次