簡體   English   中英

PHP PDO foreach 和 fetch

[英]PHP PDO with foreach and fetch

以下代碼:

<?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();
}

Output:

Connection is successful!

person A-male
person B-female

運行“foreach”兩次不是我的目的,我只是好奇為什么兩個“foreach”語句只有一次 output 結果?

以下是類似案例:

<?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();
}

Output:

Connection is successful!

person A-male
person B-female

SCREAM: Error suppression ignored for
Warning: Invalid argument supplied for foreach()

但是當我從上面的代碼中刪除第一個“foreach”時,output 將變得正常:

<?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();
}

Output:

Connection is successful!

user_id-0000000001
name-person A
sex-male

為什么會這樣?

PDOStatement (您在$users )是一個前向光標。 這意味着,一旦使用(第一次foreach迭代),它就不會倒回到結果集的開頭。

您可以在foreach之后關閉游標並再次執行該語句:

$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進行緩存:

$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對象的所有屬性和方法。

語句上的 foreach 只是常規單向 fetch() 循環的語法糖。 如果要多次循環數據,請先將其選擇為常規數組

$sql = "SELECT * FROM users";
$stm = $dbh->query($sql);
// here you go:
$users = $stm->fetchAll();

foreach ($users as $row) {
    print $row["name"] . "-" . $row["sex"] ."<br/>";
}
echo "<br/>";
foreach ($users as $row) {
    print $row["name"] . "-" . $row["sex"] ."<br/>";
}

也退出那個try..catch東西。 不要使用它,而是為 PHP 和 PDO 設置正確的錯誤報告

這是因為您正在讀取游標,而不是數組。 這意味着您正在按順序閱讀結果,當您讀到最后時,您需要將光標重置到結果的開頭才能再次閱讀它們。

如果您確實想多次讀取結果,您可以使用fetchAll將結果讀入一個真正的數組,然后它會按您的預期工作。

$users = $dbh->query($sql);
foreach ($users as $row) {
    print $row["name"] . "-" . $row["sex"] ."<br/>";
}
foreach ($users as $row) {
    print $row["name"] . "-" . $row["sex"] ."<br/>";
}

這里$users是一個PDOStatement對象,您可以對其進行迭代。 第一次迭代輸出所有結果,第二次不執行任何操作,因為您只能迭代一次結果。 那是因為數據是從數據庫流式傳輸的,並且使用foreach迭代結果本質上是以下內容的簡寫:

while ($row = $users->fetch()) ...

完成該循環后,您需要在數據庫端重置游標,然后才能再次循環它。

$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/>";
}

這里所有結果都由第一個循環輸出。 fetch的調用將返回false ,因為您已經用盡了結果集(見上文),因此您在嘗試遍歷false會遇到錯誤。

在最后一個示例中,您只是獲取第一個結果行並對其進行循環。

$row = $db->getAllRecords(DB_TBLPREFIX . '_payplans', '*', ' AND ppid = "' . $myid . '"');
foreach ($row as $value) {
    $bpprow = array_merge($bpprow, $value);
}

這基於 PHP 函數,您可以在其中全局使用此數據。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM