常规的为递归方式,但是在如果是用在地区分类这种几万条的数据上就会明显变慢,我尝试了包括(mysql查询结果存成一个数组以减少数据库查询次数)等方法,但还是明显感觉很慢。我的数据量大概是45000条左右,递归方式优化后大概用时10秒左右。
这里介绍一种引用的无限极分类方式 ,转载自PHP中文网,(但是我改了它的一个地方,我觉得他写错了,代码处会提到)
/**
* 先生成类似下面的形式的数据
* [
* 'id'=>1,
* 'pid'=>0,
* 'items'=>[
* [
* 'id'=>2,
* 'pid'=>'1'
],
*
*
* [
* 'id'=>3,
* 'pid'=>'1'
*
* ]
* 。。。
* ]
* ]*/
function getTree($list, $pid = 0)
{
$tree = [];
if (!empty($list)) { //先修改为以id为下标的列表
$newList = [];
foreach ($list as $k => $v) {
$newList[$v['id']] = $v;
} //然后开始组装成特殊格式
foreach ($newList as $value) {
if ($pid == $value['pid']) {//先取出顶级
//&为引用 不懂可以百度搜索php引用
$tree[] =&$newList[$value['id']];
} elseif (isset($newList[$value['pid']])) {//再判定非顶级的pid是否存在,如果存在,则再pid所在的数组下面加入一个字段items,来将本身存进去
$newList[$value['pid']]['items'][] = &$newList[$value['id']];
}
}
} return $tree;
}
这样递归就很快了
function formatTree($tree)
{
$options = [];
if (!empty($tree)) {
foreach ($tree as $key => $value) {
//php中文网原文为 $options[$value['id']] = $value['name'];到底怎么写可以自己思考一下
//$this->n 为函数外定义的变量初始化为0
$options[$this->n++] = ["name"=>$value['name'],"level"=>$value['level']];
if (isset($value['items'])) {//查询是否有子节点
$optionsTmp = $this->formatTree($value['items']);
if (!empty($optionsTmp)) {
$options = array_merge($options, $optionsTmp);
}
}
}
}
return $options;
}