2010-11-22 6 views
0

J'ai un DB comme ceci:fonction PHP récursive pour l'affichage contiguïté liste

id text   parent 
1 Parent 1  0 
2 Child of 1  1 
3 Sibling   1 
4 Another Parent 0 
5 A first child 4 

Je suis en train de capturer une structure arborescente ma liste des parents. Je suis conscient de l'autre option (jeux imbriqués je pense?) Mais je vais m'en tenir à cela pour l'instant. J'essaie maintenant de sortir les données de la base de données et dans une structure de tableau imbriquée dans PHP. J'ai une fonction comme ceci:

class Data_Manager 
{ 
    public $connection = ''; 
    public $collection = array(); 

    function __construct() { 
     $this->connection = mysql_connect('localhost', 'root', 'root'); 
     $thisTable = mysql_select_db('data'); 
      // error handling truncated 
    } 


    function get_all() { 
     $arr = &$this->collection; 

     $this->recurseTree('', 0, $arr); 
     var_dump($arr); 
    } 

    function recurseTree($parent, $level, $arrayNode) { 
     $result = mysql_query('SELECT * FROM tasks WHERE parent="' . $parent . '";'); 

     while ($row = mysql_fetch_array($result)) { 
      $row['children'] = array(); //where I'd like to put the kids  
      $arrayNode[$row['id']]= $row; 
      $this->recurseTree($row['id'], $level+1, $arrayNode[$row['id']]); 
     } 
    } 
} 

Donc ce que je voudrais sortir avec une sorte d'arbre imbriqué de tableaux associatifs, mais je ne peux pas comprendre tout à fait comment faire. Rien ne semble être écrit dans le tableau que je passe, et je suis en quelque sorte perdre la trace de moi-même dans la récursivité. Quelqu'un peut-il me aider à franchir cette dernière bosse qui se traduira par quelque chose comme:

[ 
Parent1 => [ 
       children => ['Child of 1', 'Sibling'] 
      ], 
AnotherParent => [ 
        children => ['First Child'] 
       ] 
] 

Je suis moins préoccupé par la forme spécifique de la sortie. Il sera transformé en JSON et je n'ai pas encore traité de l'écriture du gestionnaire côté client, donc pas de soucis sur la structure exacte.

Merci!

+0

Avez-vous essayé de passer par la référence? – stillstanding

+0

Je le fais quand je passe dans la variable d'instance originale $ collection; Je ne sais pas grand-chose sur la façon dont cela fonctionne, mais devrais-je l'utiliser tout au long de la récursivité pour toujours modifier le tableau 'mère'? –

+0

voir http://stackoverflow.com/questions/3627878/php-mysql-retrieve-a-single-path-in-the-adjacency-list-model pour beaucoup de référence –

Répondre

0

Ce bit de pseudo-code devrait aider.

function getTasks($parent = 0){ 
    $tasks = array(); 
    $query = mysql_query("select * from table where parent = $parent"); 
    $rows = array(); 
    while(($row = mysql_fetch_assoc($query)) !== FALSE){ $rows[] = $row; } 
    if(count($rows)){ 
     $tasks[$parent][] = getTasks($parent); 
    } else { 
     return $tasks; 
    } 
} 

$tasks = getTasks();
5

Essayez ceci.

$sql = "SELECT * FROM tasks"; 
$r = mysql_query($sql, $conn); 
$arr = array(); 
while ($row = mysql_fetch_assoc($r)) 
    $arr[] = $row 

function build($arrayIn, $parent) 
{ 
    $makeFilter = function($p) {return function($x) use ($p) {return $x['parent'] == $p;};}; 
    $f = $makeFilter($parent); 
    $these = array_filter($arrayIn, $f); 
    $remaining = array_diff_assoc($arrayIn, $these); 
    $ans = array(); 

    foreach($these as $cur) 
    { 
     $ans[$cur['text']] = build($remaining, $cur['id']); 
    } 
    return $ans ? $ans : null; 
} 

$tree = build($arr, 0) 
echo_r($arr); 
echo "becomes<br />"; 
echo_r($tree); 

Voici ma sortie:

Array 
(
[0] => Array 
    (
     [text] => a 
     [id] => 1 
     [parent] => 0 
    ) 

[1] => Array 
    (
     [text] => b 
     [id] => 2 
     [parent] => 0 
    ) 

[2] => Array 
    (
     [text] => c 
     [id] => 3 
     [parent] => 1 
    ) 

[3] => Array 
    (
     [text] => d 
     [id] => 4 
     [parent] => 2 
    ) 

[4] => Array 
    (
     [text] => e 
     [id] => 5 
     [parent] => 2 
    ) 

[5] => Array 
    (
     [text] => f 
     [id] => 6 
     [parent] => 3 
    ) 

) 

becomes 

Array 
(
[a] => Array 
    (
     [c] => Array 
      (
       [f] => 
      ) 

    ) 

[b] => Array 
    (
     [d] => 
     [e] => 
    ) 

) 
0

Vous avez vraiment pas besoin d'une fonction récursive ici. Obtenez toutes les données en utilisant une requête de base de données et bouclez dessus. Ce sera beaucoup plus rapide que plusieurs appels de base de données.

En supposant que vous stockez les données dans MySQL, see the answer to this question for instructions on how to write a SELECT statement against an Adjacency List table that returns everything in a hierarchy. En bref, utilisez les variables de session MySQL. Ensuite, prenez le resultset et bouclez dessus, utilisez une pile pour pousser - pop - peek le dernier parent id pour déterminer l'indentation de vos structures de données.