1

次のデータを含むデータベース テーブルがあります。

categoryId    categoryName    parentCategory
men           Men             root
women         Women           root
shoes         Shoes           root
mensshirts    Men's Shirts    men
menspants     Men's Pants     men
mensjeans     Men's Jeans     men
mensvests     Men's Vests     men
womensshirts  Women's Shirts  women
womenpants    Women's Pants   women

階層化されたメニューを印刷するために再帰関数を使用しています。コードは以下です。

function display_children($parent) {
    global $connect;
    $query = "SELECT categoryId, categoryName FROM categories WHERE parentCategory='$parent'";
    $result = mysqli_query($connect,$query);

    if ( $result === false ) {
       printf("Query Error: %s\n", mysqli_error($connect));
       exit();
    }

    echo "<ul>";
    while ($row = mysqli_fetch_assoc($result)) {
       extract($row);
       echo "<li>".$categoryName."</li>";
       display_children($categoryId);   
    }
    echo "</ul>";

    mysqli_close($connect);
}

display_children('root');

その結果、これを画面に出力します。

  • 男性
    • メンズシャツ
    • メンズパンツ
    • メンズジーンズ
    • メンズベスト
  • 女性

再帰関数は残りのサブキャットを出力していません。その理由はわかりません。私のテスト/デバッグでは、mensvests が categoryId として関数に渡された後、次に渡される categoryId が women であることが確認されており、最後のサブキャットを見つける必要があります。何か案は?

4

3 に答える 3

1

正直なところ、これに対するアプローチを再評価し、関数を廃棄する必要があります。再帰関数でクエリを実行することは、問題を探しているだけです。50 の異なるカテゴリのブランチがある場合、それらを表示するためだけに 50 ほどのクエリを本当に実行したいですか? MySQL を使用した階層データの管理に関するこの記事を読む必要があります。適切なアプローチを使用することで、複数のクエリではなく 1 つのクエリを実行できます。あなたのシナリオに当てはまる記事の例:

SELECT t1.name AS lev1, t2.name as lev2, t3.name as lev3, t4.name as lev4
FROM category AS t1
LEFT JOIN category AS t2 ON t2.parent = t1.category_id
LEFT JOIN category AS t3 ON t3.parent = t2.category_id
LEFT JOIN category AS t4 ON t4.parent = t3.category_id

この記事では、ネストされたセット モデルに従うことを実際に推奨していることに注意してください。

于 2012-11-30T20:56:42.520 に答える
0

関数の最後に DB 接続を閉じています。再帰的な反復の場合、最初の再帰が完全な深さに達した後は、使用する接続がありません。

より良いアプローチは、db接続をパラメーターとして関数に渡すことです

function display_children($parent, $db) {
    // when you recurse call
    display_children($categoryId, $db);
}

display_children('root', $connect);
mysqli_close($connect);
于 2012-11-30T20:55:03.953 に答える
0

あなたの問題は、「return」ステートメントの代わりに「exit」を使用しているという事実にあると思います。さらに、あなたはあなたの接続を閉じます

mysqli_close($connect);

それはあなたがしたいことではありません。exit はプログラム全体を停止しますが、return (値 tu return を指定しなくても) は関数を終了するだけです。

次に、アルゴリズムを変更する必要があります。これは、これを行う正しい方法ではありません。

私にとっては、最初にすべての結果を取得し ( を使用mysqli_fetch_all)、正しい順序で表示できるように配列を並べ替えるのが最善の方法です。

于 2012-11-30T20:56:05.040 に答える