問題描述
以下代碼:
<?php
try {
$dbh = new PDO("mysql:host=$hostname;dbname=$dbname", $username, $password);
echo "Connection is successful!<br/>";
$sql = "SELECT * FROM users";
$users = $dbh->query($sql);
foreach ($users as $row) {
print $row["name"] . "-" . $row["sex"] ."<br/>";
}
foreach ($users as $row) {
print $row["name"] . "-" . $row["sex"] ."<br/>";
}
$dbh = null;
}
catch (PDOexception $e) {
echo "Error is: " . $e-> etmessage();
}
輸出:
Connection is successful!
person A-male
person B-female
運行foreach"兩次不是我的目的,我只是好奇為什么兩個foreach"語句只輸出一次結果?
Running "foreach" twice is not my purpose, I'm just curious why TWO "foreach" statements only output the result once?
以下是類似的情況:
<?php
try {
$dbh = new PDO("mysql:host=$hostname;dbname=$dbname", $username, $password);
echo "Connection is successful!<br/>";
$sql = "SELECT * FROM users";
$users = $dbh->query($sql);
foreach ($users as $row) {
print $row["name"] . "-" . $row["sex"] ."<br/>";
}
echo "<br/>";
$result = $users->fetch(PDO::FETCH_ASSOC);
foreach($result as $key => $value) {
echo $key . "-" . $value . "<br/>";
}
$dbh = null;
}
catch (PDOexception $e) {
echo "Error is: " . $e-> etmessage();
}
輸出:
Connection is successful!
person A-male
person B-female
SCREAM: Error suppression ignored for
Warning: Invalid argument supplied for foreach()
但是當我從上面的代碼中刪除第一個foreach"時,輸出會變得正常:
But when I delete the first "foreach" from the above codes, the output will become normal:
<?php
try {
$dbh = new PDO("mysql:host=$hostname;dbname=$dbname", $username, $password);
echo "Connection is successful!<br/>";
$sql = "SELECT * FROM users";
$users = $dbh->query($sql);
echo "<br/>";
$result = $users->fetch(PDO::FETCH_ASSOC);
foreach($result as $key => $value) {
echo $key . "-" . $value . "<br/>";
}
$dbh = null;
}
catch (PDOexception $e) {
echo "Error is: " . $e-> etmessage();
}
輸出:
Connection is successful!
user_id-0000000001
name-person A
sex-male
為什么會發生這種情況?
Why does this happen?
推薦答案
A PDOStatement
(您在 $users
中有)是一個前向光標.這意味著,一旦使用(第一次 foreach
迭代),它就不會倒回到結果集的開頭.
A PDOStatement
(which you have in $users
) is a forward-cursor. That means, once consumed (the first foreach
iteration), it won't rewind to the beginning of the resultset.
可以在foreach
之后關閉游標,再次執行語句:
You can close the cursor after the foreach
and execute the statement again:
$users = $dbh->query($sql);
foreach ($users as $row) {
print $row["name"] . " - " . $row["sex"] . "<br/>";
}
$users->execute();
foreach ($users as $row) {
print $row["name"] . " - " . $row["sex"] . "<br/>";
}
或者你可以使用定制的 CachingIterator
和完整緩存來緩存:
Or you could cache using tailored CachingIterator
with a fullcache:
$users = $dbh->query($sql);
$usersCached = new CachedPDOStatement($users);
foreach ($usersCached as $row) {
print $row["name"] . " - " . $row["sex"] . "<br/>";
}
foreach ($usersCached as $row) {
print $row["name"] . " - " . $row["sex"] . "<br/>";
}
您找到CachedPDOStatement
類作為要點.緩存迭代器可能比將結果集存儲到數組中更合理,因為它仍然提供它所包裝的 PDOStatement
對象的所有屬性和方法.
You find the CachedPDOStatement
class as a gist. The caching iterator is probably more sane than storing the result set into an array because it still offers all properties and methods of the PDOStatement
object it has wrapped.
這篇關于帶有 foreach 和 fetch 的 PHP PDO的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!