PHPの質問です!下記のようにテーブル(category)を抽出するWhile文の中で得られた値(cate_id)を参照し、異なるテーブル(m_group)データをWhile文で値を抽出しようとしましたが…この入れ子に記述したwhile文のループが終わった時点で、親のWhile文のループが1回で終わってしまいます。なぜでしょうか? 解決の糸口を、ご存知の方がいましたら…ご教授いただけると助かります。よろしくお願いします!


echo "<nav id=\"gropCntl\"><ul>";
$res = $db->query("SELECT * FROM category WHERE shop_id=?; ", array($shop_id));
if (PEAR::isError($res)) {die("カテゴリー・抽出エラー:");}
 while ($row = $res->fetchRow(DB_FETCHMODE_ASSOC)) {
 echo "<li class=\"naviMenu\" onmouseover=\"this.className='naviMenu_on'\"
 onmouseout=\"this.className='naviMenu'\">
 <a href=\"\">".htmlspecialchars($row["cate_name"],ENT_QUOTES)."</a>";
 echo "<ul class=\"sub\">";
 $res = $db->query("SELECT * FROM m_group WHERE g_cate_id=? AND shop_id=?",
 array(htmlspecialchars($row["cate_id"],ENT_QUOTES), $shop_id));
 if (PEAR::isError($res)) {die("グループ・抽出エラー:");}
while ($row = $res->fetchRow(DB_FETCHMODE_ASSOC)) {
echo "<li><a href=\"\">".htmlspecialchars($row["group_name"],ENT_QUOTES)."</a></li>";
}
echo "</ul></li>";
}
echo "</ul></nav>";

回答の条件
  • 1人5回まで
  • 登録:
  • 終了:2012/03/02 18:16:50
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:namiheikun No.1

回答回数75ベストアンサー獲得回数6

ポイント100pt

厳密に言うとPHPの話では無いのですが
データベースハンドル$dbを一つで行ってるからです
入れ子にする場合は2カーソルで行うべきです
$db = connectDb();
$db2 = connectDb();
$res1=$db->query(...);
while ($row=$res->fetch()){
......
$res2= $db2->query(....);
while ($row2=$res2->fetch()) {
.....
}
}
こんな感じかな

id:DrArabes

早速のご返信、ありがとうございます!解決いたしました。

そのような理由だったんですね…たいへん勉強になりました!

2012/03/02 18:16:19

その他の回答1件)

id:namiheikun No.1

回答回数75ベストアンサー獲得回数6ここでベストアンサー

ポイント100pt

厳密に言うとPHPの話では無いのですが
データベースハンドル$dbを一つで行ってるからです
入れ子にする場合は2カーソルで行うべきです
$db = connectDb();
$db2 = connectDb();
$res1=$db->query(...);
while ($row=$res->fetch()){
......
$res2= $db2->query(....);
while ($row2=$res2->fetch()) {
.....
}
}
こんな感じかな

id:DrArabes

早速のご返信、ありがとうございます!解決いたしました。

そのような理由だったんですね…たいへん勉強になりました!

2012/03/02 18:16:19
id:tdoi No.2

回答回数174ベストアンサー獲得回数75

ポイント50pt

$resの使いまわしが原因ですね。

変数を分けるか、

echo "<nav id=\"gropCntl\"><ul>";
$res1 = $db->query("SELECT * FROM category WHERE shop_id=?; ", array($shop_id));
if (PEAR::isError($res1)) {die("カテゴリー・抽出エラー:");}
while ($row = $res1->fetchRow(DB_FETCHMODE_ASSOC)) {
   echo "<li class=\"naviMenu\" onmouseover=\"this.className='naviMenu_on'\"
   onmouseout=\"this.className='naviMenu'\">
   <a href=\"\">".htmlspecialchars($row["cate_name"],ENT_QUOTES)."</a>";
   echo "<ul class=\"sub\">";
   $res2 = $db->query("SELECT * FROM m_group WHERE g_cate_id=? AND shop_id=?", 
   array(htmlspecialchars($row["cate_id"],ENT_QUOTES), $shop_id));
   if (PEAR::isError($res2)) {die("グループ・抽出エラー:");}
    while ($row = $res2->fetchRow(DB_FETCHMODE_ASSOC)) {
      echo "<li><a href=\"\">".htmlspecialchars($row["group_name"],ENT_QUOTES)."</a></li>";
    }
    echo "</ul></li>";
}
echo "</ul></nav>"; 

こんな感じで、関数とかで逃げるとか。

echo "<nav id=\"gropCntl\"><ul>";
$res = $db->query("SELECT * FROM category WHERE shop_id=?; ", array($shop_id));
if (PEAR::isError($res)) {die("カテゴリー・抽出エラー:");}
while ($row = $res->fetchRow(DB_FETCHMODE_ASSOC)) {
   echo "<li class=\"naviMenu\" onmouseover=\"this.className='naviMenu_on'\"
   onmouseout=\"this.className='naviMenu'\">
   <a href=\"\">".htmlspecialchars($row["cate_name"],ENT_QUOTES)."</a>";
    outputGroup($row['cate_id'], $shop_id);
}
echo "</ul></nav>"; 

function outputGroup($category_id, $shop_id)
{
   echo "<ul class=\"sub\">";
   $res = $db->query("SELECT * FROM m_group WHERE g_cate_id=? AND shop_id=?", 
   array(htmlspecialchars($category_id,ENT_QUOTES), $shop_id));
   if (PEAR::isError($res)) {die("グループ・抽出エラー:");}
    while ($row = $res->fetchRow(DB_FETCHMODE_ASSOC)) {
      echo "<li><a href=\"\">".htmlspecialchars($row["group_name"],ENT_QUOTES)."</a></li>";
    }
    echo "</ul></li>";
}


何かの参考になれば。

id:DrArabes

早速の返信、ありがとうございます。関数で逃げるっていう方法もあるんですね。無事に解決しました。ご教授ありがとうございます!たいへん、勉強になりました。

2012/03/02 18:21:10
id:tdoi

関数で逃げるというのが正しい表現ではないですが、関数内は変数のスコープが変わるので、同名でも違う変数として扱われるために、こういった回避も可能です。

2012/03/02 18:26:37
  • id:tdoi
    水を差すようでなんですが、コネクションを複数作る必要はないかと・・・。
  • id:namiheikun
    Cとかでやってたら2カーソルでやらないと出来なかったので(カーソルでリザルトセット持ってたので)
    リザルトセットをオブジェクトで作られるならリザルトセットを分けるだけで可能でしょうね
  • id:tdoi
    ストアドプロシジャか何かと勘違いされているのかとも思いましたが、そういうラッパーのライブラリがあるのかもしれませんね。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません