Mehrere Datensätze in eine MySQL-Datenbank mit PHP einfügen
Mehrere Datensätze gleichzeitig in eine Datenbank einzufügen erhöht die Effizienz Ihrer Anwendung erheblich, besonders bei großen Datenmengen.
Datensätze einzeln einzufügen bedeutet pro Zeile einen Roundtrip zum Datenbankserver – langsam und verschwenderisch, wenn Hunderte oder Tausende von Zeilen geladen werden müssen. Indem man sie zu einem einzigen INSERT-Statement bündelt, kann MySQL den gesamten Batch einmal parsen, planen und schreiben – was erheblich schneller ist.
Dieses Kapitel zeigt drei Wege, mehrere Zeilen mit der mysqli-Erweiterung von PHP einzufügen:
- Ein einzelnes
INSERT ... VALUES (...), (...)Statement — das einfachste und schnellste Masseneinfügen. - Ein Prepared Statement in einer Schleife über die Daten — sicher gegen SQL-Injection, ideal wenn die Werte von Benutzern stammen.
mysqli_multi_query()— mehrere verschiedene Statements in einem einzigen String ausführen.
Falls Sie sich noch nicht mit einer Datenbank verbunden haben, beginnen Sie mit Verbindung zu MySQL mit PHP. Zum Einfügen einer einzelnen Zeile siehe Daten in MySQL einfügen.
Eine Verbindung herstellen
Jedes der folgenden Beispiele setzt eine offene mysqli-Verbindung in $conn voraus. Wir erstellen sie mit mysqli_connect() und brechen frühzeitig ab, wenn sie fehlschlägt:
<?php
$servername = "localhost";
$username = "username";
$password = "password";
$dbname = "database_name";
// Create connection
$conn = mysqli_connect($servername, $username, $password, $dbname);
// Check connection
if (!$conn) {
die("Connection failed: " . mysqli_connect_error());
}
echo "Connected successfully";
?>Methode 1: Ein INSERT mit mehreren Wertemengen
Der schnellste Weg, viele Zeilen hinzuzufügen, ist ein einzelnes INSERT INTO-Statement, das mehrere kommagetrennte Wertemengen auflistet. MySQL fügt sie alle in einem einzigen Vorgang ein:
<?php
$sql = "INSERT INTO users (firstname, lastname, email)
VALUES ('John', 'Doe', '[email protected]'),
('Mary', 'Moe', '[email protected]'),
('Julie', 'Dooley', '[email protected]')";
if (mysqli_query($conn, $sql)) {
// mysqli_affected_rows() reports how many rows were inserted
$count = mysqli_affected_rows($conn);
echo "$count records inserted successfully.";
} else {
echo "Error inserting records: " . mysqli_error($conn);
}
?>mysqli_query() nimmt zwei Argumente — die Verbindung und den SQL-String — und gibt bei Erfolg true oder bei Fehler false zurück. Nach einem erfolgreichen Einfügen zeigt mysqli_affected_rows() an, wie viele Zeilen tatsächlich geschrieben wurden (hier 3).
Verwenden Sie diese Methode, wenn die Daten vertrauenswürdig sind (hartkodiert oder bereits bereinigt). Da die Werte direkt in den SQL-String eingebettet werden, ist sie nicht sicher für rohe Benutzereingaben — das behebt Methode 2.
Methode 2: Prepared Statement in einer Schleife
Wenn die Werte aus einem Formular, einer API oder einer anderen nicht vertrauenswürdigen Quelle stammen, erstellen Sie die Abfrage mit einem Prepared Statement, sodass die Daten getrennt vom SQL übertragen werden. Das blockiert SQL-Injection und ermöglicht die Wiederverwendung desselben kompilierten Statements für jede Zeile:
<?php
$users = [
['John', 'Doe', '[email protected]'],
['Mary', 'Moe', '[email protected]'],
['Julie', 'Dooley', '[email protected]'],
];
// Prepare once with placeholders
$stmt = mysqli_prepare($conn, "INSERT INTO users (firstname, lastname, email) VALUES (?, ?, ?)");
// Bind PHP variables to the placeholders ("sss" = three strings)
mysqli_stmt_bind_param($stmt, "sss", $firstname, $lastname, $email);
foreach ($users as [$firstname, $lastname, $email]) {
mysqli_stmt_execute($stmt); // runs with the current variable values
}
echo count($users) . " records inserted safely.";
mysqli_stmt_close($stmt);
?>Der Typ-String "sss" teilt MySQL mit, dass die drei gebundenen Parameter Strings sind. Verwenden Sie i für Integer, d für Doubles/Floats und b für Blobs. Eine vollständige Erklärung finden Sie unter PHP MySQL Prepared Statements.
Für maximale Geschwindigkeit bei Tausenden von Zeilen umschließen Sie die Schleife mit einer Transaktion, damit MySQL einmal statt nach jedem Execute committet:
<?php
mysqli_begin_transaction($conn);
foreach ($users as [$firstname, $lastname, $email]) {
mysqli_stmt_execute($stmt);
}
mysqli_commit($conn);
?>Methode 3: mysqli_multi_query()
Die obigen Methoden fügen in eine Tabelle mit einem Statement ein. Wenn Sie mehrere verschiedene Statements auf einmal ausführen müssen — beispielsweise das Einfügen in zwei Tabellen — verwenden Sie mysqli_multi_query(), das mehrere durch Semikolons getrennte SQL-Statements aus einem einzigen String ausführt:
<?php
$sql = "INSERT INTO users (firstname, lastname) VALUES ('John', 'Doe');";
$sql .= "INSERT INTO users (firstname, lastname) VALUES ('Mary', 'Moe');";
$sql .= "INSERT INTO logs (action) VALUES ('bulk import')";
if (mysqli_multi_query($conn, $sql)) {
echo "Multiple statements executed successfully.";
} else {
echo "Error: " . mysqli_error($conn);
}
?>Achtung:
mysqli_multi_query()akzeptiert beliebig gestapelte Statements und ist daher riskant bei Benutzereingaben — bauen Sie den String niemals aus nicht vertrauenswürdigen Daten auf. Für einfache Masseneinfügungen bevorzugen Sie Methode 1 oder Methode 2.
Die eingefügten IDs abrufen
Nach dem Einfügen gibt mysqli_insert_id() die AUTO_INCREMENT-ID zurück, die von der zuletzt eingefügten Zeile generiert wurde. Bei einem Mehrfach-Insert liefert sie die ID der ersten Zeile des Batches; nachfolgende Zeilen folgen sequenziell. Einzelheiten finden Sie unter Die ID des zuletzt eingefügten Datensatzes abrufen.
Die Verbindung schließen
mysqli schließt die Verbindung automatisch, wenn das Skript endet, aber es ist gute Praxis, sie explizit freizugeben, sobald man fertig ist:
<?php
mysqli_close($conn);
?>Welche Methode soll ich verwenden?
| Situation | Beste Wahl |
|---|---|
| Vertrauenswürdige, feste Daten; maximale Geschwindigkeit | Methode 1 — ein INSERT mit mehreren Wertemengen |
| Werte von Benutzern / externer Eingabe | Methode 2 — Prepared Statement in einer Schleife |
| Mehrere verschiedene Statements auf einmal | Methode 3 — mysqli_multi_query() |
Fazit
Das Bündeln von Einfügungen verwandelt viele langsame Roundtrips in eine schnelle Operation. Greifen Sie auf ein einzelnes INSERT mit mehreren Wertemengen zurück, wenn die Daten vertrauenswürdig sind, auf ein Prepared Statement in einer Schleife (für große Batches in einer Transaktion), wenn sie von Benutzern stammen, und auf mysqli_multi_query() nur dann, wenn Sie wirklich verschiedene Statements zusammen ausführen müssen. Validieren Sie unabhängig von der Methode Ihre Eingaben und prüfen Sie mysqli_error(), damit Fehler nie stillschweigend übergangen werden.