Obwohl in einer Datenbankfunktion mit einem Prepared Statement Query die Anzahl der Platzhalter mit der Anzahl der übergebenen Werte überein stimmte, gab es folgende Fehlermeldung:

PDOStatement::execute() pdostatement.execute SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens in ...

Ich hatte ein Array mit 5 IDs übergeben und einen Query mit eben genau 5 Platzhaltern gehabt.

$allIds = [...];
$ids = array_unique($allIds);

$placeholders = (count($ids) > 1) ? str_repeat("?,", count($artistIds)-1)."?" : "?";
$query = "SELECT ... FROM ... WHERE aID IN (".$placeholders.") ...";
$stmt = $this->persistenceManager->prepare($query);
$stmt->execute($ids);

In Klartext übersetzt, sah der Query also so aus:

SELECT ... FROM ... WHERE aID IN (?, ?, ?, ?, ?) ...

Und das Array sah eigentlich auch gut aus:

var_dump($ids);

// Ausgabe:
//
// array(3) {
//   [0]=> int(42)
//   [4]=> int(69)
//   [5]=> int(666)
//   [6]=> int(1024)
//   [9]=> int(123456)
// }

Eigentlich nur aus Zufall nahm ich war, dass die Schlüssel des Arrays nicht durchgängig numeriert waren, sondern Lücken in der Zählung hatten. Das resultiert aus der array_unique() Anweisung, die dafür sorgt, dass doppelte Werte rausgefiltert werden. Um die Schlüssel neu lückenlos aufsteigend zu generieren, packte ich noch ein array_values() darum:

$ids = array_values(array_unique($allIds));

// Ergebnis:
//
// array(3) {
//   [0]=> int(42)
//   [1]=> int(69)
//   [2]=> int(666)
//   [3]=> int(1024)
//   [4]=> int(123456)
// }

Und siehe da: der Query wurde ohne Fehlermeldung korrekt ausgeführt!

Ich hab keine Ahnung, ob das ein allgemein bekanntes Verhalten von Prepared Statements über PDO-Objekte ist. Ich vermute mal, dass bei "?" Platzhaltern die numerischen Keys des Arrays die Position bestimmen und wenn ein Key einen höheren Wert hat, als überhaupt Platzhalter da sind, dann knallt es halt.

Mir war das jedenfalls nicht bewusst. Ich ging irgendwie davon aus, dass bei "?" Platzhaltern und einem normalen Arrays einfach alles in der gegebenen Reihenfolge eingesetzt wird. Aber da kann man mal wieder sehen, wie solche Kleinigkeiten Minuten an Fehlersuche verursachen können.