2010-11-22 11 views
0

Ich habe ein DB wie so:rekursive PHP-Funktion für adjacency-Listenanzeige

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

Also versuche ich, eine Baumstruktur meiner Auflistung der Eltern zu erfassen. Ich bin mir der anderen Möglichkeit bewusst (verschachtelte Sets, denke ich?), Aber ich bleibe dabei. Ich versuche nun, die Daten aus der DB und in eine verschachtelte Array-Struktur in PHP zu bekommen. Ich habe eine Funktion wie folgt aus:

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']]); 
     } 
    } 
} 

Also, was ich möchte mit kommen irgendeine Art von verschachtelten Baum von assoziativen Arrays ist, aber ich kann nicht herausfinden, ganz wie das zu tun. Nichts scheint in das Array zu schreiben, in das ich gehe, und ich verliere den Überblick über mich selbst in der Rekursion. Kann mir jemand helfen über diesen letzten Buckel, die in so etwas wie führen:

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

Und ich bin weniger um die spezifische Form des Ausgangs. Es wird in JSON umgewandelt und ich habe mich noch nicht damit beschäftigt, den clientseitigen Handler zu schreiben, also keine Sorge wegen der genauen Struktur.

Danke!

+0

haben Sie versucht, per Referenz zu übergeben? – stillstanding

+0

tue ich, wenn ich die ursprüngliche Instanzvariable $ collection übergebe; Ich weiß nicht viel darüber, wie das funktioniert, aber sollte ich das alles durch Rekursion verwenden, um immer das "Mutter" -Array zu bearbeiten? –

+0

siehe http://stackoverflow.com/questions/3627878/php-mysql-retrieve-a-single-path-in-the-adjacency-list-model für eine Menge von Referenz –

Antwort

0

Dieses bisschen Pseudo-Code sollte helfen.

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

Versuchen Sie dies.

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

Hier ist meine Ausgabe:

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

Sie wirklich nicht brauchen, eine rekursive Funktion hier. Holen Sie alle Daten mit einer Datenbankabfrage und durchlaufen Sie sie. Es wird viel schneller als mehrere Datenbankaufrufe sein.

Angenommen, Sie speichern die Daten in 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. Kurz gesagt, verwenden Sie MySQL-Sitzungsvariablen. Dann nehmen Sie die Ergebnismenge und Schleife über sie, verwenden Sie einen Stapel, um zu drücken - Pop - peek die letzte Eltern-ID, um Einrückung Ihrer Datenstrukturen zu bestimmen.