2011-08-12 26 views
1

私は、MySQLデータベースからページとその親ページのリストを返して、すべての結果を次のように配列に入れます。すべての結果は、フォーラムの親、名前、およびIDを含む配列です(配列ページのキーもページIDと同じです)。リストからPHPビルド再帰配列

モデルとアプリケーションのために、いくつかの他のパラメータがあります。

  • "ルート・ページは、" 何の孤立したページ

はそうはありません0

  • の親を持って、MySQLのクエリは、このデータセットを返します。

    pages=> 
        [1] => array(id=>1, 
            parent=>0, 
            name=>Hello World) 
        [2] => array(id=>1, 
            parent=>1, 
            name=>Child of Hello World) 
        [3] => array(id=>1, 
            parent=>0, 
            name=>Brother of Hello World) 
        [4] => array(id=>4, 
            parent=>2, 
            name=Grand-child of Hello World) 
        [6] => array(id=>6, 
            parent=>4, 
            name=Great-grand-child of Hello World) 
    

    私はその後、私は私のサイトマップを印刷できるように、ネストされた多次元配列にリニアアレイを有効にする、だから、基本的にこの

    pages=> 
        [1] => id=>1, 
          name=>Hello World 
          children=> 
    
           [2] => id=>1 
             name=>Child of Hello World 
             children=> 
    
              [4] => 
              id=>4 
              name=> Grand-child of Hello World) 
              children=> 
    
               [6] => 
                id=>6 
                name=> Great-grand-child of Hello World 
                children= null 
    
        [3] => array(id=>1, 
            name=>Brother of Hello World 
            children=>null 
    

    のように見えるものに、配列を変換したいです。

    これは再帰的な解決策である必要があります。 700ページ以上、最大5または6レベルがあります。

    私は1つのmysqlクエリを行いたいです。 700ではないので、私にはMySQLベースのソリューションを教えてください。

  • +2

    お好みの検索エンジンを使用して、両方のループは、配列の各要素を正確に一度に見ることを示すことができるため、「MySQLのネストされたセット」 – knittl

    答えて

    7
    <?php 
    
    $pages = array(); 
    $pages[1] = array('id' => 1, 'parent' => 0, 'name' => 'Hello World'); 
    $pages[2] = array('id' => 1, 'parent' => 1, 'name' => 'Child of Hello World'); 
    $pages[3] = array('id' => 1, 'parent' => 0, 'name' => 'Brother of Hello World'); 
    $pages[4] = array('id' => 4, 'parent' => 2, 'name' => 'Grand-child of Hello World'); 
    $pages[6] = array('id' => 6, 'parent' => 4, 'name' => 'Great-grand-child of Hello World'); 
    
    $children = array(); 
    foreach($pages as $key => $page){ 
        $parent = (int)$page['parent']; 
        if(!isset($children[$parent])) 
         $children[$parent] = array(); 
        $children[$parent][$key] = array('id' => $page['id'], 'name' => $page['name']); 
    } 
    
    $new_pages = recursive_append_children($children[0], $children); 
    
    function recursive_append_children($arr, $children){ 
        foreach($arr as $key => $page) 
         if(isset($children[$key])) 
          $arr[$key]['children'] = recursive_append_children($children[$key], $children); 
        return $arr; 
    } 
    
    print_r($new_pages); 
    
    ?> 
    

    出力:ここ

    Array 
    (
        [1] => Array 
         (
          [id] => 1 
          [name] => Hello World 
          [children] => Array 
           (
            [2] => Array 
             (
              [id] => 1 
              [name] => Child of Hello World 
              [children] => Array 
               (
                [4] => Array 
                 (
                  [id] => 4 
                  [name] => Grand-child of Hello World 
                  [children] => Array 
                   (
                    [6] => Array 
                     (
                      [id] => 6 
                      [name] => Great-grand-child of Hello World 
                     ) 
    
                   ) 
    
                 ) 
    
               ) 
    
             ) 
    
           ) 
    
         ) 
    
        [3] => Array 
         (
          [id] => 1 
          [name] => Brother of Hello World 
         ) 
    ) 
    
    +0

    これはO(N)時間計算量を検索してください。 – Paulpro

    +0

    ご返信ありがとうございます。それをデータ配列全体に調整するために少し微調整を行いましたが、すばらしい答えがありました。 そのため、$ children [$ parent] [$ key] = array( 'id' => $ page ['id']、 'name' => $ page ['name']); は$ children [$ parent] [$ key] = $ pages [$ key]です。 – j6mes

    +0

    @Partydroidよろしくお願いします。違いは、得られた配列に 'parent'値を保持することです。これは、あなたが取り除こうと思っていたようです。あなたはいつも 'unset($ children [$ parent] [$ key] ['parent'])でもできます。 – Paulpro

    7

    はツリーを構築し、迅速再帰関数です。それは素晴らしいことではないことに注意してください(ツリーにすでに追加されているアイテムを取り除かないために1つの理由があります。そのため、リスト全体を繰り返し実行するたびに、リストが表示されます)。

    function buildTree($itemList, $parentId) { 
        // return an array of items with parent = $parentId 
        $result = array(); 
        foreach ($itemList as $item) { 
        if ($item['parent'] == $parentId) { 
         $newItem = $item; 
         $newItem['children'] = buildTree($itemList, $newItem['id']); 
         $result[] = $newItem; 
        } 
        } 
    
        if (count($result) > 0) return $result; 
        return null; 
    } 
    
    $myTree = buildTree($myArray, 0); 
    
    +0

    助けてくれてありがとう。私はこれを使用しませんでしたが、私は次回どのようにそれをやるのよいアイデアをくれました。 – j6mes