遇到这个问题几天了,终于在所有的同子项目中其它功能都做完之后,决定开始做这个
可以先看看分类结构图

其实无限级栏目就像类似的多循环结构,直到最后没有内容循环为止
也就是说,在整个栏目处理中,整个栏目关联就是靠父栏目ID来构造的
所以,我模拟了一个多级分类,如下图,id是栏目id,pid是父栏目ID
$array = array(
1=>0,
2=>1,
3=>2,
7=>1,
4=>0,
5=>4,
6=>5,
);
一个随意模拟的三级目录结构
那么首先我要做的一件事,就是将顶级栏目取出来,然后通过顶级栏目获取到二级栏目
foreach($array as $k=>$v){
if($v==$pid){
$list[] = $k;
}
}
foreach($list as $k=>$v){
$clist[$v] = str_repeat(' ',0);
foreach($array as $k1=>$v1){
if($v1==$v){
$list1[] = $k;
}
}
}
我突然发现,内容居然循环了,也就是说,我如果给循环部定义一个函数,如果这个栏目存在子栏目,那么就调用自己
为了节约整个循环时间,我并不是通过判断是否无法循环退出(貌似也很判断),而是每取出一个栏目,就删除$array的一个键,直到$array为空的时候,自然循环就终止了。
所以,整个代码循环就出来了
/*
* 显示多级栏目表
* @param $array栏目数组结构信息 array(栏目ID=>父栏目ID,)
* @param $pid要搜索的父栏目ID 0为顶级栏目
* @param $strpad间隔字符
* @param $padnum要间隔的字符数量
*/
function keach(&$array,$pid=0,$pad=0,$padnum='++'){
static $clist = array();//定义一个静态数组变量,这样取出来的值可以循环添加键值对
$list = array();//初始化一个数组
foreach($array as $k=>$v){//循环分类数组,找到指定父栏目的栏目ID
if($v==$pid){
$list[] = $k;
unset($array[$k]);//找到后销毁,下一个循环就少一次判断了,直到$array为空
}
}
if(!empty($list)){//如果栏目不为空,也就是这个父栏目下面还有栏目,就要循环自身调取数据
foreach($list as $k=>$v){//以上面获取到的栏目ID为父ID,判断是否存在子栏目
//echo str_repeat($padnum,$pad).$v.'
';
$clist[$v] = str_repeat($padnum,$pad);
keach($array,$v,$pad+2);
}
}
return $clist;
}
最后打印结果
print_r(keach($array,0));
打印出来的结果是:
Array
(
[1] =>
[2] => ++++
[3] => ++++++++
[7] => ++++
[4] =>
[5] => ++++
[6] => ++++++++
)
2天后
终于发现了一个问题,由于要计算目录下所有的子目录,多次调用居然结果一模一样,坑爹的static,在子进程循环中是不能被注销的,而且初始化后就不叫static了,经过左思右想,决定定义一个全局变量,但是每次使用前都初始化一次,万一忘记了呢,所以,出现了下面的代码
/**
* 初始化多级栏目显示,防止递归产生值错误
* @param array $array栏目数组结构信息 array(栏目ID=>父栏目ID,)
* @param string $pid要搜索的父栏目ID 0为顶级栏目
* @param string $pad间隔字符
* @param int $padnum要间隔的字符数量
* @return array()
*/
function keach($array,$pid=0,$pad=0,$padnum='++'){
global $clist;
$clist = array();
return keachdo($array,$pid,$pad);
}
/**
* 显示多级栏目层次表
* @param array $array栏目数组结构信息 array(栏目ID=>父栏目ID,)
* @param string $pid要搜索的父栏目ID 0为顶级栏目
* @param string $pad间隔字符
* @param int $padnum要间隔的字符数量
* @return array()
*/
function keachdo($array,$pid=0,$pad=0,$padnum='++'){
global $clist;
$list = array();
foreach($array as $k=>$v){
if($v==$pid){
$list[] = $k;
unset($array[$k]);
}
}
if(!empty($list)){
foreach($list as $k=>$v){
$clist[$v] = str_repeat($padnum,$pad);
keachdo($array,$v,$pad+1);
}
}
return $clist;
}
八年后(2020年)补充,其实在早几年我就收藏了比较简洁的写法,主要用来生成带有层级关系的多维数组,而我以前写的代码在当前前后端分离的概念下不是很适用。这个写法据说是一位C大神写的,这里放到我的博文下面,巧妙运用数组引用赋值来实现生成分类结构。
function createTree($items) {
$tree = array();
foreach ($items as $item) {
if (isset($items[$item['pid']])){
$items[$item['pid']]['son'][] = &$items[$item['id']];
} else {
$tree[] = &$items[$item['id']];
}
}
return $tree;
}
//生成一个以id为键的数组,数据库读取出来的数据需要预先处理
$items = array(
1=>array('id'=>1,'pid'=>0, 'extend'=>'....'),
2=>array('id'=>2,'pid'=>1, 'extend'=>'....'),
3=>array('id'=>3,'pid'=>2, 'extend'=>'....'),
4=>array('....');
);
createTree($items);
这篇博客探讨了如何在PHP中实现无限级分类,通过递归和数组操作构建多级目录结构。作者首先展示了初始实现,然后发现了静态变量在递归过程中的问题,导致结果错误。为了解决这个问题,作者改用了全局变量并重新组织了代码。最后,博客提到了一种更简洁的创建分类结构的方法,利用数组引用赋值,提高了效率。
7223

被折叠的 条评论
为什么被折叠?



