加入收藏 | 设为首页 | 会员中心 | 我要投稿 南平站长网 (https://www.0599zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

PHP无限分类实例程序

发布时间:2022-02-13 21:45:34 所属栏目:PHP教程 来源:互联网
导读:无限分类的原理:就像windows下新建一个文件夹,在新建的文件夹下又可以新建一个文件夹,这样无限循环下去,无限分类也是这样,父类可以分出它子类,子类又可以分出它的子类,这样一直无限循环下去. 例1,代码如下: $yArr = array( 1 = array(id=1,parentid=0,name
  无限分类的原理:就像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    = emptyempty($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);//递归调用
           }//开源代码Cuoxin.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三者的关系即可.
 
 

(编辑:南平站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读