如何用PHP递归方法,将数组变成树型结构(SQL 方法和 非SQL 两种方法)
2018-01-26| 程成| 1655| 0| PHP技术

你会遇到许多树型结构存在同一张表中,他们通过 "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”方法好太多。





×
作者:程成
QQ:492245711