IN() und PDO: Array richtig binden – Die 5 häufigsten Fehler

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Einleitung: „Warum versteht PDO mein Array nicht?“

\n

Jeder PHP-Entwickler, der mit Datenbanken arbeitet, steht früher oder später vor der Aufgabe, eine Abfrage mit dem IN()-Operator auszuführen. Klingt einfach: Ein Array mit Werten übergeben und die gefilterten Daten erhalten. Doch genau hier liegt die Tücke.

\n

Hier ein klassisches Beispiel, das einem Anfänger in den Sinn kommt:

\n
<?php\n$ids = [1, 2, 3, 5];\n$stmt = $pdo->prepare("SELECT * FROM users WHERE id IN (:ids)");\n$stmt->execute([':ids' => $ids]); // Fehler!\n?>
\n

Und PDO wirft einen Fehler: „Array to string conversion“ oder liefert einfach ein leeres Ergebnis. Warum? PDO kann Arrays nicht automatisch in SQL-Abfragen „entfalten“. Es erwartet einen skalaren Wert für jeden benannten Platzhalter, nicht ein ganzes Array.

\n

In diesem Artikel zeigen wir die häufigsten Fehler, die Entwickler beim Binden eines Arrays an IN() machen, und präsentieren korrekte, sichere und effiziente Lösungen.

\n\n

Fehler Nr. 1: Naives Übergeben eines Arrays an execute()

\n

Dies ist der häufigste Fehler. Der Entwickler denkt, PDO würde automatisch jeden Wert aus dem Array in die IN()-Bedingung einsetzen. Aber wie wir gesehen haben, funktioniert PDO so nicht.

\n

Wie es im Code aussieht

\n
<?php\n$ids = [10, 20, 30];\n$stmt = $pdo->prepare("SELECT * FROM products WHERE id IN (:ids)");\n$stmt->execute([':ids' => $ids]); // Fatal error\n?>
\n

Ergebnis: Fehler oder Warnung wegen Umwandlung eines Arrays in einen String. Selbst wenn der Code „durchrutscht“, setzt PDO das Wort „Array“ in die Abfrage ein – und Sie erhalten WHERE id IN ('Array'), was sinnlos ist.

\n

Warum passiert das? PDO erwartet, dass jedem Platzhalter ein einzelner Wert entspricht. Ein Array ist kein Wert, sondern eine Sammlung von Werten. PDO kann und soll nicht erraten, was Sie vorhaben.

\n\n

Fehler Nr. 2: Verwendung von bindValue() mit einem Array

\n

Manchmal versuchen Entwickler, PDO mit bindValue() auszutricksen:

\n
<?php\n$ids = [1, 2, 3];\n$stmt = $pdo->prepare("SELECT * FROM users WHERE id IN (:ids)");\n$stmt->bindValue(':ids', $ids, PDO::PARAM_STR); // Fehler!\n$stmt->execute();\n?>
\n

Das gleiche Problem: bindValue() erwartet einen skalaren Wert. Das Array wird in den String „Array“ umgewandelt, und die Abfrage wird nicht korrekt ausgeführt. Der dritte Parameter (PDO::PARAM_STR) hilft nicht – er gibt nur den Datentyp an, ändert aber nichts an der Logik der Array-Verarbeitung.

\n\n

Fehler Nr. 3: Direkte Konkatenation (SQL-Injection)

\n

Verzweifelt wählen manche Entwickler den Weg des geringsten Widerstands – sie setzen das Array einfach per implode() in die Abfrage ein:

\n
<?php\n$ids = [1, 2, 3];\n$ids_str = implode(',', $ids);\n$stmt = $pdo->query("SELECT * FROM users WHERE id IN ($ids_str)"); // Gefährlich!\n?>
\n

Warum ist das gefährlich? Wenn die Werte im Array vom Benutzer stammen (z. B. aus GET-Parametern oder Formularen), kann ein Angreifer 1; DROP TABLE users; -- übergeben. Die Abfrage wird zu IN (1; DROP TABLE users; --), und Ihre Datenbank ist zerstört. Das ist eine klassische SQL-Injection.

\n

Selbst wenn Sie sicher sind, dass die Daten sicher sind, ist diese Praxis schlechter Stil. Irgendwann vergessen Sie, die Datenquelle zu prüfen, und die Folgen können katastrophal sein.

\n\n

Die richtige Lösung: Dynamische Platzhalter

\n

Jetzt zu den guten Nachrichten. PDO erlaubt es, Platzhalter dynamisch zu erstellen. Sie müssen einen String mit der benötigten Anzahl von ? oder :id1, :id2, ... generieren und das Array mit Werten separat übergeben.

\n

Methode 1: Verwendung von Positions-Platzhaltern (?)

\n

Dies ist die einfachste und beliebteste Methode:

\n
<?php\n                

Blogs

Buchempfehlungen