天天看點

php 如何把查詢的有關聯的資料格式轉換為樹狀格式

一提到樹狀格式,就感覺好像很高大上,其實查詢資料庫也可以查出這樣的格式,但是可能需要在sql上的能力稍微強一些,另外簡單的方法也就是查詢完了再循環查了,但是這種方式十分的耗費資源,性能很低,如果産品上線并發一上來肯定是不行的,是以不建議這樣做。哪如何才能簡單的查詢,又提高效率呢,就是從代碼中來解決這樣的問題,效率高查詢還簡單。

先了解一下需求吧,比如關聯效果,那種地區的三級關聯,多級分類,多級菜單。我們可以發現。其實大部分這種需求的資料量并不大。那就先說一下,解決問題的邏輯。首先先把資料一次性都查出來(非常簡單的sql),拿到資料以後,先根據最高父級id來把最外層取到,然後再根據最外層的父級id再資料中拿出來放到最外層的資料集中,以此類推,你需要多少級,那麼就處理多少層就解決了。當然我用的這個方法也是可以繼續優化的,比如說讓他無限處理到最底層,但是一般這種需求我們碰不到,一般也就兩三層。是以我隻封裝兩個方法來使用就足夠了。

1、控制器

/***
     * @return mixed
     * @author lifang
     * @info 擷取分類清單(公共使用)
     */
    public function cateList()
    {
        $arrData = app(Categorys::class)->getAll();
        
        $arrCate = parentTree($arrData);

        return json_response($arrCate,'擷取成功',200);
    }
           

2、處理最外層資料,公共調用方法,這裡也可以把資料排序加上,我沒加,如果你的需求有,哪加個排序方法處理,可以把你的資料固定位置

/***
 * @param $arrData
 * @param int $sParent
 * @return array
 * @author lifang
 * @info 基礎處理
 */
function tree( $arrData,$sParent=0 )
{
    $arrNew = [];
    foreach ( $arrData as $key=>$value )
    {
        if ( $value['pid'] == $sParent )
        {
            $arrNew[] = $value;
        }
    }
    return $arrNew;
}
           

3、内層資料

/***
 * @param $arrData
 * @return array
 * @author lifang
 * @info 組裝内層
 */
function parentTree( $arrData )
{
    if ( !is_array($arrData) || count($arrData) < 1 )
    {
        return [];
    }
    $arrNew = tree($arrData);
    foreach ( $arrNew as $k=>$v)
    {
        $arrNew[$k]['parent'] = tree($arrData,$v['id']);
    }
    return $arrNew;
}