你会遇到许多树型结构存在同一张表中,他们通过 "parent_id" 关联着。那么如何将他们取出,并变成 "树型结构" 呢?下面提供了两种方法可以实现(一种是 PHP 的递归方法,一种是 SQL 的递归方法)。
PHP 递归方法(非 SQL):
/** * [getTreeByData 获取树型结构--非sql版本] * @author zhuhui * @date 2018-01-17 * @version [0.1] * @param $results * @param $data * @param $id * @param $parent_id * @return mixed */ public static function getTreeByData($results, $data, $id, $parent_id = 'parent_id'){ foreach ($data as $k=>$d){ $d['child'] = []; $i = $d['id']; if ($d[$parent_id] == $id){ unset($data[$k]); $results[$id]['child'][$i] = $d; } } if (isset($results[$id])){ foreach($results[$id]['child'] as $n=>$v){ $one = self::getTreeByData($v, $data, $n); if (isset($one[$n])){ $results[$id]['child'][$n]['child'] = $one[$n]['child']; } } } return $results; }
这里有4个参数:
$results 是返回的结果,第一次调用的时候传空数组,因为需要递归调用自身,必须得传;
$data 是数据数组;
$id 是关系字段的第一层的值,也就是树型结构最外层的 "parent_id";
$parent_id 是父子的关系字段,我这里默认是 "parent_id"。
注:上面是保留数组 key 的方法,下面提供一个子数组不保留 key 的方法
/** * 把二维数组转化为树状结构数组 * * [@since] 2016-12-05 * [@author] mingazi@163.com * [@param] array $arr 要处理的数组 * [@param] string $pid 父级ID的值,默认是0 * @param string $idName id的名称,默认是id * @param string $pidName pid的名称,默认是pid * @param string $childName 下级的key名称,默认是child * @return array $tree 生成的树状数组 */ public function createTree($arr = array(), $pid = 0, $idName = 'id', $pidName = 'pid', $childName = 'child') { $tree = array(); foreach($arr as $k => $v) { if($v[$pidName] == $pid) { $tmp = $arr[$k]; unset($arr[$k]); $tmp[$childName] = self::createTree($arr,$v[$idName],$idName,$pidName,$childName); $tree[] = $tmp; } } return $tree; }
PHP 递归方法(SQL):
/** * [getTreeBySql 获取树型结构--sql版本] * @author zhuhui * @date 2018-01-17 * @version [0.1] * @param $db "db" * @param $sql "SELECT * FROM modules WHERE parent_id = " * @param $id 0 * .example getTreeBySql('db',"SELECT * FROM modules WHERE parent_id = ",0) * @return array */ public static function getTreeBySql($db,$sql,$id){ $records = Yii::$app->$db->createCommand($sql.$id)->queryAll(); $data = []; foreach($records as $k=>$d){ $data[$d['id']] = $d; } unset($records); foreach($data as $n=>$d){ $data[$n]['child'] = self::getTreeBySql($db,$sql,$n); } return $data; }
这里有3个参数:
$db 是连接的数据库;
$sql 是执行的sql语句,这里相当于 SELECT * FROM modules WHERE parent_id = ";
$id 是关系字段的第一层的值,也就是树型结构最外层的 "parent_id"。
通过上面两个方法,你可以递归的将数组变成树型结构。这里尽量用“非SQL”方法,性能比“SQL”方法好太多。