1

これは私が持っているPHPコードです:

while($row1 = mysql_fetch_object($query1)) {
   echo "*".$row1->id."*";
   while ($row2 = mysql_fetch_object($query2)) {
      echo "%".$row2->id."%";
   }
}

たとえば、次のように出力します。*1*%1%%2%%3%%4%*2*%1%%2%%3%%4%*3*%1%%2%%3%%4%

しかし、このループの出力は次のとおりです。*1*%1%%2%%3%%4%*2**3*

($row1 の最初のループで $row2 の値のみを出力します。

どうすればこれを修正できますか? ありがとう。

4

6 に答える 6

1

について注意すべき点がいくつかありmysql_fetch_object()ます。PHP ドキュメントから:

警告: この拡張機能は PHP 5.5.0 で非推奨になりました

以上ご了承ください。

フェッチされた行に対応するプロパティを持つオブジェクトを返し、内部データ ポインターを前方に移動します。

私が太字にしたことに注意してください。

$resultオブジェクト (コードでは)$query2は、現在のアイテムを指すポインターを持つ反復オブジェクトです。

Current Item
 |
 v
[1][2][3][4]

最初のループが 2 番目のループに到達すると、全体が繰り返され、最終的にオブジェクトは次のようになります。

         Current Item
          |
          v
[1][2][3][4]

最初のループの各反復では、最初のループの後、mysql_fetch_object()関数は基本的に次のようになります。

mysql_fetch_object() ~
  1. Get the next time
  2. Uh, there are no more objects because we're at item [4].  Return done.

では、どうやってそれを機能させるのですか?結果を単純に配列に保存してから、その配列を反復処理するか、ポインターをリセットすることができますmysql_data_seek()(これも 5.5 で非推奨になりました)。

データ ポインタをリセットするには、次のようにします。

while($row1 = mysql_fetch_object($query1)) {
   echo "*".$row1->id."*";
   while ($row2 = mysql_fetch_object($query2)) {
      echo "%".$row2->id."%";
   }
   // put the result pointer back to the front
   mysql_data_seek($query2, 0)
}

注1、このSOの質問/回答は、ポインターをリセットするために使用する機能を見つけるのに役立ちました。

欠点は、オブジェクトを作成する関数を呼び出すことであり、実行するたびに処理のオーバーヘッドが発生することに注意してください。

もう 1 つのオプションは、結果を配列に保存し、毎回配列をループすることです。

$secondary_result = array();
while ($row2 = mysql_fetch_object($query2)) {
  $secondary_result[] = $row2;
}

while($row1 = mysql_fetch_object($query1)) {
    echo "*".$row1->id."*";
    foreach($secondary_result as $row2) {
        echo "%".$row2->id."%";
    }
}

このメソッドは、オブジェクトを配列に格納するために余分なメモリ使用量を作成しますが、オブジェクトを何度も再作成したり、関数を呼び出したりする必要がないため、CPU 処理を節約できます。

出力を印刷するだけの場合は、最初に結果を保存することを検討できます。何回ループしても$secondary_result、最終結果は常に同じになります (コードによると、最初のループは 2 番目の結果に直接影響を与える兆候を示しません)。

その場合、これははるかに理にかなっています

$buffer = '';
while ($row2 = mysql_fetch_object($query2)) {
  $buffer .= "%".$row2->id."%";
}

while($row1 = mysql_fetch_object($query1)) {
    echo "*".$row1->id."*";
    echo $buffer;
}

しかし、なぜあなたがそんなことをするのか、私には本当にわかりません。ネストされたループを実行している場合、通常は最初のループの結果が 2 番目のループに影響を与えているためです。

しかし、それが役立つことを願っています!

乾杯!

編集

@Blazemonger の今後の見通しに関するコメントによると、同等の PDO は次のようになります。MySqli:Fetch-Object

PDO 関数を使用して結果オブジェクトを取得すると、次のようにループします。

while($row1 = $query1->fetch_object()) {
   echo "*".$row1->id."*";
   while ($row2 = $query1->fetch_object()) {
      echo "%".$row2->id."%";
   }
   // put the result pointer back to the front
   $query2->data_seek(0);
}

上記の例は、MySqli のフェッチ オブジェクトとポインター リセット バージョンの両方を示しています。

于 2013-05-01T19:30:42.483 に答える
1

問題は、 を完全に反復する$query2と、結果が終了することです。次回の$row1ループでは、まだ最後に$query2いて、結果が残っていません。mysql_data_seek結果の最初に戻るために使用してみてください。

while($row1 = mysql_fetch_object($query1)) {
   echo "*".$row1->id."*";
   mysql_data_seek($query2, 0);
   while ($row2 = mysql_fetch_object($query2)) {
      echo "%".$row2->id."%";
   }
}
于 2013-05-01T19:08:18.097 に答える
1

2 番目のクエリ データを何度も繰り返す必要がある場合は、最初にそれを配列に取得し、必要な回数だけこの配列をループします。

于 2013-05-01T19:08:27.127 に答える
1

まず第一に:mysql_*関数は非推奨であり、PHP 5.5 で削除されます。代わりにmysqliまたはPDOの使用を検討してください。

そうは言っても; あなたの質問に戻ります:

各結果セットには、結果セット内のレコードの 1 つへの内部ポインタが含まれています。最初、このポインタは最初のレコードを指し、 を呼び出すたびに進められmysql_fetch_objectます。

最初の内部ループの後、$query2結果セットの内部ポインターは既にリストの最後にあるため、後続の呼び出しmysql_fetch_objectは のみを返しFALSEます。

内側のクエリが の値に依存している場合は$row1、外側のループ内で 2 番目のクエリを再実行する必要があります。それ以外の場合は、 で結果ポインタをリセットできますmysql_data_seek

于 2013-05-01T19:09:10.727 に答える
0

最初のループの後、query2 が返す結果はもうありません。そのため、while はfalse追加の各ループにあります。クエリをリセットするmysqli_data_seekか、すべてのデータを別の配列に格納し、代わりにそれをループすることをお勧めします。

また、注意してください:ドキュメントhttp://us2.php.net/manual/en/function.mysql-fetch-object.phpごと

mysql 拡張機能は PHP 5.5.0 で非推奨になり、将来的に削除される予定です。代わりに、MySQLi または PDO_MySQL エクステンションを使用する必要があります

于 2013-05-01T19:08:18.020 に答える
0

おそらく、取得している出力が得られる $row2 = mysql_fetch_object($query2) を呼び出しても、何も得られないでしょう。

于 2013-05-01T19:08:23.640 に答える