query
In diesem Artikel wird die Funktion mysqli_query() in PHP erläutert, mit der SQL-Abfragen gegen eine MySQL-Datenbank ausgeführt werden.
$mysqli->query() führt eine einzelne SQL-Anweisung über eine offene MySQLi-Verbindung gegen eine MySQL-Datenbank aus. Es ist der einfachste Weg, von PHP aus mit MySQL zu kommunizieren, also ein guter Ausgangspunkt — aber wie Sie weiter unten sehen werden, sollten Sie bei Abfragen mit Benutzereingaben auf Prepared Statements zurückgreifen.
Diese Seite erklärt, was query() zurückgibt, wie man ein Ergebnisset ausliest, wie es sich bei Schreibabfragen verhält und welche SQL-Injection-Falle Sie vermeiden müssen.
Syntax
// Object-oriented style
$result = $mysqli->query($sql);
// Procedural style
$result = mysqli_query($mysqli, $sql);Beide Formen tun dasselbe; der OOP-Stil wird auf dieser Seite durchgehend verwendet.
Was query() zurückgibt
Der Rückgabewert hängt von der Art der ausgeführten Anweisung ab:
| Abfragetyp | Bei Erfolg | Bei Fehler |
|---|---|---|
SELECT, SHOW, DESCRIBE, EXPLAIN | ein mysqli_result-Objekt | false |
INSERT, UPDATE, DELETE, CREATE, ... | true | false |
Da ein Fehler immer false zurückgibt, können Sie den Rückgabewert mit einem einfachen if prüfen. Gehen Sie niemals davon aus, dass eine Abfrage erfolgreich war — ein falsch geschriebener Spaltenname oder eine fehlende Tabelle liefern beide false.
Eine SELECT-Abfrage ausführen
Bei einem SELECT iterieren Sie über das zurückgegebene Ergebnis und lesen jede Zeile mit fetch_assoc() (oder fetch_array()) aus und geben das Ergebnis anschließend frei:
<?php
$mysqli = new mysqli("localhost", "username", "password", "database");
// Stop early if the connection failed.
if ($mysqli->connect_errno) {
echo "Failed to connect to MySQL: " . $mysqli->connect_error;
exit();
}
$result = $mysqli->query("SELECT id, name FROM users");
if ($result) {
while ($row = $result->fetch_assoc()) {
echo $row["id"] . ": " . $row["name"] . "\n";
}
$result->free(); // release the result set's memory
} else {
echo "Query failed: " . $mysqli->error;
}
$mysqli->close();
?>Die while-Schleife endet, wenn fetch_assoc() null zurückgibt (keine weiteren Zeilen). $result->free() gibt das Ergebnisset frei, was bei lang laufenden Skripten mit vielen Abfragen wichtig ist.
INSERT, UPDATE und DELETE ausführen
Schreibabfragen geben kein Ergebnisset zurück — bei Erfolg geben sie true zurück. Um zu erfahren, wie viele Zeilen betroffen waren, lesen Sie $mysqli->affected_rows; um die Auto-Increment-ID einer frisch eingefügten Zeile zu erhalten, lesen Sie $mysqli->insert_id:
<?php
$mysqli = new mysqli("localhost", "username", "password", "database");
if ($mysqli->query("UPDATE users SET active = 1 WHERE active = 0")) {
echo $mysqli->affected_rows . " rows updated";
} else {
echo "Query failed: " . $mysqli->error;
}
$mysqli->close();
?>Benutzereingaben niemals direkt in eine Abfrage einsetzen
query() nimmt einen rohen SQL-String entgegen. Das Verketten von Benutzereingaben damit öffnet die Tür für SQL-Injection — die häufigste Datenbanksicherheitslücke im Web:
// DANGEROUS — do NOT do this
$id = $_GET['id'];
$result = $mysqli->query("SELECT * FROM users WHERE id = $id");Wenn ein Besucher id=0 OR 1=1 sendet, gibt diese Abfrage jeden Benutzer zurück. Die Lösung ist ein Prepared Statement, das SQL und Werte getrennt überträgt, sodass die Werte niemals als SQL interpretiert werden können:
$stmt = $mysqli->prepare("SELECT * FROM users WHERE id = ?");
$stmt->bind_param("i", $_GET['id']); // "i" = integer
$stmt->execute();
$result = $stmt->get_result();Verwenden Sie query() nur für festes SQL ohne Benutzereingaben; verwenden Sie Prepared Statements für alles, was Werte aus externen Quellen enthält. Eine vollständige Anleitung finden Sie unter MySQL Prepared Statements.
Zusammenfassung
$mysqli->query()führt eine SQL-Anweisung auf einer offenen MySQLi-Verbindung aus.- Ein
SELECTgibt einmysqli_result-Objekt zurück, über das Sie mitfetch_assoc()iterieren; andere Anweisungen gebentruezurück; jeder Fehler gibtfalsezurück. - Lesen Sie
affected_rowsnach einer Schreiboperation undinsert_idnach einemINSERT. - Wechseln Sie zu Prepared Statements, sobald Benutzereingaben im Spiel sind.