2011-08-12 6 views
1

Je retourne une liste de pages et leurs pages parent à partir d'une base de données MySQL et de mettre tous les résultats dans un tableau comme suit où chaque résultat est un tableau qui comprend le parent, le nom et l'id du forum (la clé des pages de tableau est également la même que celle de la page). Pour les besoins du modèle et de l'application, il existe d'autres paramètres.PHP Construire récursive tableau de la liste

  • "pages racine" ont un parent de 0
  • il n'y a pas pages orphelines

donc, la requête MySQL retournera cet ensemble de données.

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) 

je voudrais ensuite transformer le tableau en quelque chose qui ressemble à ceci

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 

Donc, fondamentalement, je veux tourner un réseau linéaire dans un tableau multidimensionnel imbriqué afin que je puisse imprimer mon plan Sitemap .

il doit s'agir d'une solution récursive. il y a plus de 700 pages et jusqu'à 5 ou 6 niveaux. Je veux seulement faire 1 requête mysql. pas 700 alors s'il vous plaît ne me donnez pas une solution basée sur mysql.

+2

s'il vous plaît utilisez votre moteur de recherche préféré et recherchez « MySQL ensembles imbriqués » – knittl

Répondre

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); 

?> 

Sorties:

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

Ceci est O (N) de complexité de temps, puisque les deux boucles peuvent être présentés pour regarder chaque élément du tableau exactement une fois. – Paulpro

+0

merci pour votre réponse. juste fait quelques ajustements mineurs pour l'ajuster à l'ensemble du tableau de données, mais une grande réponse merci. donc $ enfants [$ parent] [$ key] = tableau ('id' => $ page ['id'], 'name' => $ page ['nom']); est maintenant $ enfants [$ parent] [$ key] = $ pages [$ key]; – j6mes

+0

@Partydroid De rien. La seule différence est que cela gardera les valeurs 'parent' dans votre tableau résultant, dont il semble que vous vouliez vous débarrasser. Vous pouvez toujours simplement 'unset ($ children [$ parent] [$ key] ['parent']); – Paulpro

7

Voici une fonction récursive rapide qui construit un arbre. Notez que ce n'est pas génial (l'une des raisons est qu'elle ne supprime pas les éléments qui ont déjà été ajoutés à l'arborescence, donc chaque fois que vous les recurcissez, elle traverse toute la liste), mais cela devrait fonctionner suffisamment pour démarrer.

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

Merci de votre aide. Je n'ai pas utilisé cela mais m'a donné une bonne idée de comment je le ferais la prochaine fois. – j6mes

Questions connexes