問題描述
以下代碼:
<?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
運(yùn)行foreach"兩次不是我的目的,我只是好奇為什么兩個(gè)foreach"語句只輸出一次結(jié)果?
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()
但是當(dāng)我從上面的代碼中刪除第一個(gè)foreach"時(shí),輸出會(huì)變得正常:
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
為什么會(huì)發(fā)生這種情況?
Why does this happen?
推薦答案
A PDOStatement
(您在 $users
中有)是一個(gè)前向光標(biāo).這意味著,一旦使用(第一次 foreach
迭代),它就不會(huì)倒回到結(jié)果集的開頭.
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
之后關(guān)閉游標(biāo),再次執(zhí)行語句:
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
類作為要點(diǎn).緩存迭代器可能比將結(jié)果集存儲(chǔ)到數(shù)組中更合理,因?yàn)樗匀惶峁┧b的 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.
這篇關(guān)于帶有 foreach 和 fetch 的 PHP PDO的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網(wǎng)!