PHP无限分类实例程序模板.docx
《PHP无限分类实例程序模板.docx》由会员分享,可在线阅读,更多相关《PHP无限分类实例程序模板.docx(8页珍藏版)》请在冰豆网上搜索。
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
*@paramarray$data原始数组
*@paramint$id当前id
*@paramint$layer当前层级
*/
functiongenCate($data,$pid=0,$level=0)
{
if($level==10)break;
$l =str_repeat(" ",$level);
$l =$l.'└';
static$arrcat =array();
$arrcat =empty($level)?
array():
$arrcat;
foreach($dataas$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);//递归调用
}
}
return$arrcat;
}
$carr =genCate($yArr);
echo"
foreach($carras$row)
{
echo"";
echo$row['name'];
echo"";
}
echo"";
注:
因为是无限次的调用,所以我加了个判断,在层级$level=10的时候让他跳出。
没有哪个正常网站会放超过10层的
目录结构吧。
执行到static变量后,判断下当前层级,如果层级为0,那么表示这是最高级菜单,需要清空$arrcate的数据重新声明
例2
代码如下
复制代码
//我们建一个表"class"
CREATETABLE`class`(
`id`int(11)NOTNULLauto_incrementCOMMENT'分类id',
`f_id`int(11)NOTNULLCOMMENT'父id',
`name`varchar(25)collategbk_binNOTNULLCOMMENT'分类名称',
PRIMARYKEY(`id`)
)ENGINE=InnoDBDEFAULTCHARSET=gbkCOLLATE=gbk_binAUTO_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']."
"; //这样就把每个大类循环出来了。
}
//同样我们可以把新闻的子类循环出来。
$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;$iif($arr[$i][1]==$f_id){ //$arr[$i][1]表示第$i+1个分类的f_id的值。
开始$f_id=0,也就是把f_id=0的分类输出来。
echo $arr[$i][2]."
"; //$arr[$i][1]表示第$i+1个分类的name的值。
fenlei($arr[$i][0]); //$arr[$i][1]表示第$i+1个分类的id的值。
进行递归
,也就是把自己的id作为f_id参数把自己的子类再循环出来。
}
}
}
fenlei(); //使用这个函数.
?
>
例3
php无限分类,支持输出树状图
代码如下
复制代码
php
/**
*通用的树型类,可以生成任何树型结构
*/
classtree
{
/**
*生成树型结构所需要的2维数组
*@vararray
*/
var$arr=array();
/**
*生成树型结构所需修饰符号,可以换成图片
*@vararray
*/
var$icon=array('│','├','└');
/**
*@accessprivate
*/
var$ret='';
/**
*构造函数,初始化类
*@paramarray2维数组,例如:
*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'=>'三级栏目二')
* )
*/
functiontree($arr=array())
{
$this->arr=$arr;
$this->ret='';
returnis_array($arr);
}
/**
*得到父级数组
*@paramint
*@returnarray
*/
functionget_parent($myid)
{
$newarr=array();
if(!
isset($this->arr[$myid]))returnfalse;
$pid=$this->arr[$myid]['parentid'];
$pid=$this->arr[$pid]['parentid'];
if(is_array($this->arr))
{
foreach($this->arras$id=>$a)
{
if($a['parentid']==$pid)$newarr[$id]=$a;
}
}
return$newarr;
}
/**
*得到子级数组
*@paramint
*@returnarray
*/
functionget_child($myid)
{
$a=$newarr=array();
if(is_array($this->arr))
{
foreach($this->arras$id=>$a)
{
if($a['parentid']==$myid)$newarr[$id]=$a;
}
}
return$newarr?
$newarr:
false;
}
/**
*得到当前位置数组
*@paramint
*@returnarray
*/
functionget_pos($myid,&$newarr)
{
$a=array();
if(!
isset($this->arr[$myid]))returnfalse;
$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($newarras$v)
{
$a[$v['id']]=$v;
}
}
return$a;
}
/**
*-------------------------------------
* 得到树型结构
*-------------------------------------
*@author Midnight(杨云洲), yangyunzhou@
*@param$myid表示获得这个ID下的所有子级
*@param$str生成树形结构基本代码,例如:
"$select>$spacer$name"
*@param$sid被选中的ID,比如在做树形下拉框的时候需要用到
*@param$adds
*@param$str_group
*@returnunknown_type
*/
functionget_tree($myid,$str,$sid=0,$adds='',$str_group='')
{
$number=1;
$child=$this->get_child($myid);
if(is_array($child))
{
$total=count($child);
foreach($childas$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;
}
/**
*同上一方法类似,但允许多选
*/
functionget_tree_multi($myid,$str,$sid=0,$adds='')
{
$number=1;
$child=$this->get_child($myid);
if(is_array($child))
{
$total=count($child);
foreach($childas$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.'.
';
@extract($a);
eval("$nstr="$str";");
$this->ret.=$nstr;
$this->get_tree_multi($id,$str,$sid,$adds.$k.' ');
$number++;
}
}
return$this->ret;
}
functionhave($list,$item){
return(strpos(',,'.$list.',',','.$item.','));
}
}
?
>