1

私の最初の質問は、私は孤独な開発者なので、アイデアを投げ捨てたり、問題に行き詰まったときにアイデアを得るために他の人がいないのが恋しいということです。その問題を解決することに特化したサイトはありますか? 仮想共同プログラマー サイトのようなものですか? または、StackOverflow はそのように機能しますか?

私の主な質問: 私は「やること」リストのようなものに取り組んでいますが、各項目にはサブステップ、サブサブステップ、さらにはそれ以上のステップがある可能性があります。フィールド「id、item、parent_id」を持つテーブルがあり、最上位のアイテムはすべてparent_id = 0です。CodeIgniterでDatamapper ORMを使用して、これを使用しています:

$i = new Item();
$i->where('parent_id',0)->get();
foreach($i as $item) {
   echo $item->item;
   $si = new Item();
   $si->where('parent_id',$item->id)->get();
   foreach($si as $subItem) {
      echo $subItem->item;
      // and so on
   }
}

それは機能しますが、これを達成するためのよりスマートな方法はありますか? 多分ある種の再帰関数?

私はまた、他の誰かがすべてを管理する方法に取り組んでいるので、必要な場所にアイテムをドラッグ アンド ドロップするだけで済みます... しかし、それはまた別の問題です。

4

3 に答える 3

3

もし私があなたなら、ツリー構造の実装を検討するでしょう。基本的に、ここで隣接リストの基本設定を行います (DB の観点からは、PHP コードを作成してテストする必要があります)。level特定のタスクがその階層のどのレベルにあるかを定義する列を追加すると、自己結合によって 1 ~ 2 個のクエリですべてのデータを取得できますが、ネスト レベルがかなり深い場合、これは遅くなります。

別の方法は、ネストされたセットと事前注文ツリーのトラバーサルを使用することです。これは、特に各ノードに複数のブランチが必要ないように思われる場合、より多くの作業になります。

DB側から両方を詳細に説明しているMySQLでの階層データの管理を見てください...これはMySQL固有のものですが、DBにとらわれない方法で、または別の特定のDBに同じ原則を適用できるはずです。

もちろん、どちらの方法でも、PHP 側でこれのマッピングを実装する必要がありますが、これは現在行っているよりも多くの作業です...しかし、DB にアクセスする回数を減らすこともできます。

また、CI Datamapper の代わりに Doctrine (Seth も推奨) を使用することをお勧めします...これはすべて既に実装されています...Doctrine の基本を学び、CI に接続するだけでよいと確信しています。たくさんのチュートリアルがあります。

于 2010-12-28T15:33:46.633 に答える
3

独自の SQL を作成する場合、これを 3 つのクエリで実行できます

"SELECT * FROM items WHERE parent_id = 0;"
"SELECT * FROM items WHERE parent_id IN (SELECT id FROM items WHERE parent_id = 0;"

ただし、マルチネストされたツリーのような構造が必要なようです:

| item |
  | sub-item |
    | sub-sub-item |

CIを使用している場合、(私の意見では)自己参照ツリーのようなデータ構造を処理するDoctrineと呼ばれるより優れたORMがあります(提案したように再帰を使用します)。ありがたいことに、それを CodeIgniter に組み込むための素晴らしい記事があります!

http://www.phpandstuff.com/articles/codeigniter-doctrine-from-scratch-day-1-install-and-setup

Doctrine はあなたのためにクエリを構築します - それはリレーションシップや、CodeIgniter に欠けているキャッシングのような他の多くの便利な機能もサポートします:)

于 2010-12-28T15:27:45.683 に答える
0

このように、テストされていません: count($ss) は、クエリから返された結果があるかどうかを確認するのに適切な値を返さない可能性があるため、必要に応じて更新してください (Zend では Zend_Db_Table_Rowset をカウントできますが、どのオブジェクト CI かはわかりません結果の数をカウントできる場合) クエリから返された結果がある場合にのみ関数を呼び出すように if ステートメントを更新してください )

    function recursive( $i )
    {
        foreach ( $i as $item )
        {
            echo $item->item;
            $si = new Item();
            $ss = $si->where('parent_id', $item->id)->get();
            if ( count($ss) > 0 ) 
                recursive($ss);
        }
    }
    $i = new Item();
    recursive($i->where('parent_id', 0)->get());
于 2010-12-28T15:26:26.560 に答える