php的无限极分类编程包括递归,经过一段时间,终于悟懂了,记录一下:
简单但效率不高的的递归:先贴一下代码,下面我会说一下我的思路,网上查阅资料,自己悟的:
function pp(int $id){
$a = array();
$pdo = new PDO("mysql:host=127.0.0.1;dbname=test","root","");
$pdo->query("set names utf8");
$que = "select type_id,type_name from goods where parent_id=".$id;
$res = $pdo->query($que);
$all = $res->fetchAll();
for($i = 0; $i < count($all);$i++){
$a[$i]['name'] = $all[$i][1];
$a[$i]['child'] = $this->pp($all[$i][0]);
}
unset($pdo);
if(empty($a)) return null;
else return $a;
}
function printall(array $a,int $order=0){
foreach($a as $k=>$v){
echo str_repeat("--------",$order);
echo $v['name']."
";
if(!empty($v['child'])) $this->printall($v['child'],$order+1);
}
}
从pid=0开始即可查询整颗树,每一次查询都有可能查询到多个子记录,其pid等于传入的Id的,
因此我想数组有一个”name“的键,"child"的键值保存子树对应的数组结构,有点类似于
链表。便于理解,举一个例子。例如pid=0,我查到了”家用电器电脑“和”办公"两条记录,这是
最顶部的两个分类,思考一下,所以,需要向数组中添加2个元素,一个元素的name键值对应
查询到的name,child键值对应一个数组,这个数组是下一次这个函数递归查询返回的数组,而
下一次函数需要的参数就是这次查询的id,另一个元素也是,剩下所有的元素都是这样的。
下 面的那个函数是打印,递归打印,我想到的就是递归。
下面介绍非递归,高效率的巧妙方法
$pdo
=
new
PDO
(
"mysql:host=127.0.0.1;dbname=test"
,
"root"
,
"root"
);
$pdo
->
query
(
"set names utf8"
);
$stmt
=
$pdo
->
prepare
(
"select * from goods"
);
$stmt
->
execute
();
$data
=
$stmt
->
fetchAll
(
PDO
::
FETCH_ASSOC
);
$newarray
=
array
(); //仔细思考其中的引用
foreach
(
$data
as
$v
){
if
(
$v
[
'parent_id'
]
==
0
){
$newarray
[]
=
&
$data
[
$v
[
'type_id'
]
-
1
];
}
else
{
$data
[
$v
[
"parent_id"
]
-
1
][
"child"
][]
=&
$data
[
$v
[
'type_id'
]
-
1
];
}
} //
function
printall
(
$arr
,
$count
=
0
){
foreach
(
$arr
as
$v
){
echo
str_repeat
(
"------"
,
$count
);
echo
$v
[
'type_name'
];
echo
"
"
;
if
(
!
empty
(
$v
[
"child"
]))
printall
(
$v
[
"child"
],
$count
+
1
);
}
}
printall
(
$newarray
);
很巧妙,讲解一下:
创一个新的数组$newarray,循环查询出的数组$data,如果pid==0,则证明是顶级的分类
,向$newarray添加这个数组元素($newarray = $data[$v["id"]-1]),至于为什么还要减一,因
为数据库中type_id由1开始,而数组由0开始,如果pid!=0,则向$data中这个元素的父元素的数组
(就是$data[$v['pid']])中的child指向的键值中添加一个新数组($data[$v['pid']]["child"])=$data[$v[['id']];
最后就完成了。,因此这样会破坏原先数据库查出的数组,因为添加了child键,若不想,则可复制一份
,且下标从1开始,同数据库中查出的type_id一直,这样代码中就不用减一了。
printall函数递归打印,结果为: