2016-09-23 8 views
0

私は、親子行を持つデータベーステーブルを持ち、1つの親子子がフィールド "親"でリンクされています。再帰的なPHPを使用せずに親子を反復する

recursive関数をPHPで使用することで、jerarquy構造をループおよび印刷する方法はわかりましたが、1つのループコードで再現しようとすると、同じ形式でデータを表示できません。このコードのサンプルでは、​​データベーステーブル内のすべての項目が一覧表示されますが、注文していない、それは最初のトップレベルを印刷し、私は古典をしたい:

Top 1 >> Level 1 >> Level 2 >> Level 3 
    Top 2 >> Level 1 
    Top 3 >> Level 1 >> Level 2 

    $parent = array(); 
    array_push($parent, 0); 
    while(!empty($parent)){ 
    foreach($parent as $key => $mother){ 
     unset($parent[$key]);  
     $sql = "SELECT * FROM levels WHERE parent = " . $mother; 
     $res = mysql_query($sql); 
     while($row=mysqli_fetch_object($res)){ 
     print $row->name . "<br />"; 
     array_push($parent, $row->id); 
     } // while 
    } // foreach 
    } // while 

このコードの結果は

トップ1 トップであります2 上位3 レベル1 ...

+0

1つのクエリで必要なすべてのデータを選択してから何かを行う方が簡単ではないでしょうか? – simon

+0

再帰関数の場合、いくつかのSELECTを使用する方がはるかに簡単だと思います。いずれにしても、データベースとまったく同じ構造で配列が配列されていると考えることができます。それをどのように反復して、好んでデータをリストするのですか?再帰は非常に簡単ですが、私は非再帰的な方法を求めます。 – Cesar

答えて

1

ここで最大の質問は、非再帰的な方法でそれをしたいのですか?あなたが複数存在することを見て、子供ノードのレベルが決まっていないように見えるのは、再帰的な機能が優れている点です。

単純なループのみを使用する場合は、子レベルがあるのと同じ数だけネストループを作成する必要があります。または、現在のノードID、以前のノードID、および親ノードID(複数の場合)(複数)を追跡して、これを使用して新しいリーフを作成するか、リーフを終了するか、同じままにするかを決定します。
基本的にこれらの二つの方法の

Same parent == same leaf 
Different parent && parent == previous id, new leaf 
Different parent { when (parentList[idx--] == parent) == change leaf to idx leaf. 

後者がはるかに最も拡張可能であり、そして2つだけのループが必要:までツリーに戻しスプールするすべての要素の一方の主ループ、および1つの内側ループを正しい親IDが見つかりました。基本的に、再帰関数を使って自然に得られるものすべてをエミュレートします。

私がコメントしたいことは、ループ内でのクエリの使用です。これは、コードの時間消費を指数関数的に増加させるので、一般的には非常に悪いことです。親とIDでソートされた1つのクエリ内のすべてのノードを取得する方がはるかに優れています。そうすれば、(n-1)* y ms(またはそれ以上)の余分な時間を待つ必要はありません。ここで、nはレコードの数で、yはクエリを1回実行するのにかかる時間です。
クエリが実行されるのに20msかかる場合、300レコードがある場合、余分な待ち時間は約6秒です。クエリを適切にソートするのではなく、ループ内でクエリを移動したためです(またはJOINを使用する)。
ご覧のとおり、コードを適切に構造化すれば、多くのパフォーマンスが得られます。それだけでなく、あなたのコードを読んで維持するのがずっと簡単になります。

要約:ループの外でクエリを移動するため、再帰関数を使用してください。

+0

それは単なる関心事でした。ループ内のSQLクエリに関しては、あなたは完全に正しいです。私はそれを巨大な配列のPHPメモリをcosumeしないようにしましたが、私が慣れていたものとは異なる他のシナリオでは、効率を大幅に低下させるでしょう。 – Cesar

+0

うれしい私は助けることができます。特に好奇心が強いときやそうしたいときに、他の人が学ぶのを助けることができれば、いつもうれしいです。 :)良い仕事を続けてください! – ChristianF

関連する問題