wake-up-neo.com

PHP GU mit foreach und fetch

Die folgenden Codes:

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

AUSGABE:

Connection is successful!

person A-male
person B-female

Das zweimalige Ausführen von "foreach" ist nicht mein Ziel. Ich bin nur neugierig, warum ZWEI "foreach" -Anweisungen das Ergebnis nur einmal ausgeben.

Folgendes ist der ähnliche Fall:

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

AUSGABE:

Connection is successful!

person A-male
person B-female

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

Wenn ich aber das erste "foreach" aus den obigen Codes lösche, wird die Ausgabe 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();
}

AUSGABE:

Connection is successful!

user_id-0000000001
name-person A
sex-male

Weiß jemand warum das passiert? Ich bin nur ein PHP Anfänger, danke für Ihre Hilfe!

15
nut

Eine PDOStatement (die Sie in $users haben) ist ein Vorwärtscursor. Das bedeutet, dass der einmal konsumierte Iterationsschritt (foreach) nicht bis zum Anfang des Resultsets zurückspult.

Sie können den Cursor hinter der foreach schließen und die Anweisung erneut ausführen:

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

Oder Sie können den Cache mithilfe von CachingIterator mit einem Fullcache zwischenspeichern:

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

Sie suchen Sie die CachedPDOStatement-Klasse als Gist . Der Cache-Itertor ist wahrscheinlich sinnvoller als das Speichern der Ergebnismenge in einem Array, da er immer noch alle Eigenschaften und Methoden des PDOStatement-Objekts bietet, das er umbrochen hat.

19
hakre

foreach über eine Anweisung ist nur ein Syntaxzucker für die reguläre Einweg-Fetch () - Schleife. Wenn Sie Ihre Daten mehrmals wiederholen möchten, wählen Sie sie zuerst als reguläres Array aus

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

Beenden Sie auch dieses try..catch-Ding. Verwenden Sie es nicht, sondern legen Sie eine korrekte Fehlerberichterstattung für PHP und PDO fest

11

Dies liegt daran, dass Sie einen Cursor lesen, nicht ein Array. Das bedeutet, dass Sie die Ergebnisse der Reihe nach durchlesen. Wenn Sie das Ende erreicht haben, müssen Sie den Cursor an den Anfang der Ergebnisse setzen, um sie erneut lesen zu können.

Wenn Sie die Ergebnisse mehrmals durchlesen möchten, können Sie fetchAll ( http://www.php.net/manual/en/pdostatement.fetchall.php ) verwenden, um die Ergebnisse in ein echtes Array zu lesen Dann würde es funktionieren, wie Sie es erwarten.

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

Hier ist $users ein PDOStatement-Objekt, über das Sie iterieren können. Die erste Iteration gibt alle Ergebnisse aus, die zweite macht nichts, da Sie das Ergebnis nur einmal durchlaufen können. Das liegt daran, dass die Daten aus der Datenbank gestreamt werden und das Ergebnis mit foreach durchlaufen wird, ist im Wesentlichen eine Abkürzung für:

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

Wenn Sie diese Schleife abgeschlossen haben, müssen Sie den Cursor auf der Datenbankseite zurücksetzen, bevor Sie ihn erneut durchlaufen können.

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

Hier werden alle Ergebnisse von der ersten Schleife ausgegeben. Der Aufruf von fetch gibt false zurück, da Sie die Ergebnismenge bereits erschöpft haben (siehe oben), und Sie erhalten einen Fehler beim Versuch, false zu wiederholen.

Im letzten Beispiel holen Sie einfach die erste Ergebniszeile und führen eine Schleife durch.

0
deceze