Start · Sprachen · PHP · Referenz · mysqli_prepare

mysqli_prepare

Funktion

Bereitet eine SQL-Anweisung mit Platzhaltern (<code>?</code>) für die sichere, wiederholte Ausführung vor und gibt ein <code>mysqli_stmt</code>-Objekt zurück.

seit PHP 5.0.0 Kategorie: db

Signatur

mysqli_prepare(mysqli $mysql, string $query): mysqli_stmt|false

Beschreibung

mysqli_prepare() sendet eine SQL-Anweisung an den MySQL-Server, der sie kompiliert und einen Ausführungsplan erstellt, ohne sie sofort auszuführen. Parameter werden als Fragezeichen (?) angegeben und später mit mysqli_stmt_bind_param() gebunden. Dadurch werden Benutzerdaten niemals direkt in den SQL-String interpoliert, was SQL-Injection-Angriffe strukturell ausschließt.

Das Prepared-Statement-Modell ist besonders sinnvoll, wenn dieselbe Abfrage mehrfach mit unterschiedlichen Parameterwerten ausgeführt werden soll, da der Server den Ausführungsplan nur einmal erstellt. Außerdem entfällt manuelles Escaping vollständig – der Treiber übernimmt die korrekte Übertragung der Parameterwerte im binären Protokoll.

Die prozedurale Variante mysqli_prepare() verhält sich identisch zur objektorientierten Methode mysqli::prepare(). Das zurückgegebene mysqli_stmt-Objekt wird mit mysqli_stmt_bind_param(), mysqli_stmt_execute() und mysqli_stmt_bind_result() bzw. mysqli_stmt_get_result() weiterverarbeitet.

Nach der Nutzung sollte das Statement mit mysqli_stmt_close() freigegeben werden, um Ressourcen zurückzugeben.

Parameter

Name Typ Default Beschreibung
$mysql Pflicht mysqli Eine aktive MySQLi-Verbindungsressource, wie sie von mysqli_connect() oder mysqli_init() zurückgegeben wird.
$query Pflicht string Die SQL-Anweisung mit ?-Platzhaltern für Parameter. Mehrere Anweisungen in einem String (durch Semikolon getrennt) sind nicht erlaubt.

Rückgabewert

Typ
mysqli_stmt|false
Beschreibung
Bei Erfolg ein mysqli_stmt-Objekt, das das vorbereitete Statement repräsentiert. Bei einem Fehler (z. B. Syntaxfehler in der SQL-Anweisung oder fehlende Verbindung) wird false zurückgegeben. Fehlermeldungen können über mysqli_error() abgerufen werden.

Beispiele

Einfache SELECT-Abfrage mit einem Parameter

<?php
$mysqli = mysqli_connect('localhost', 'user', 'secret', 'testdb');

if (!$mysqli) {
    die('Verbindungsfehler: ' . mysqli_connect_error());
}

$stmt = mysqli_prepare($mysqli, 'SELECT id, name, email FROM users WHERE id = ?');

if ($stmt === false) {
    die('Prepare-Fehler: ' . mysqli_error($mysqli));
}

$userId = 42;
mysqli_stmt_bind_param($stmt, 'i', $userId);
mysqli_stmt_execute($stmt);

$result = mysqli_stmt_get_result($stmt);
while ($row = mysqli_fetch_assoc($result)) {
    echo $row['id'] . ': ' . $row['name'] . ' – ' . $row['email'] . PHP_EOL;
}

mysqli_stmt_close($stmt);
mysqli_close($mysqli);
42: Max Mustermann – max@example.com

INSERT mit mehreren Parametern und Fehlerbehandlung

<?php
$mysqli = new mysqli('localhost', 'user', 'secret', 'testdb');

if ($mysqli->connect_errno) {
    die('Verbindungsfehler: ' . $mysqli->connect_error);
}

// Prozeduraler Stil mit mysqli_prepare
$stmt = mysqli_prepare(
    $mysqli,
    'INSERT INTO users (name, email, age) VALUES (?, ?, ?)'
);

if ($stmt === false) {
    die('Prepare fehlgeschlagen: ' . mysqli_error($mysqli));
}

$name  = 'Erika Musterfrau';
$email = 'erika@example.com';
$age   = 30;

mysqli_stmt_bind_param($stmt, 'ssi', $name, $email, $age);

if (mysqli_stmt_execute($stmt)) {
    echo 'Eingefügt: ' . mysqli_stmt_affected_rows($stmt) . ' Zeile(n).' . PHP_EOL;
    echo 'Neue ID: '   . mysqli_stmt_insert_id($stmt) . PHP_EOL;
} else {
    echo 'Fehler: ' . mysqli_stmt_error($stmt) . PHP_EOL;
}

mysqli_stmt_close($stmt);
mysqli_close($mysqli);
Eingefügt: 1 Zeile(n). Neue ID: 7

// Wichtig · Fallstricke

Sicherheit: Prepared Statements sind der empfohlene Weg, um SQL-Injection zu verhindern. Benutzereingaben werden niemals direkt in den SQL-String eingefügt, sondern über das binäre Protokoll sicher übertragen. Ein manuelles Escaping mit mysqli_real_escape_string() ist daher überflüssig und sollte nicht kombiniert werden.

Tabellen- und Spaltennamen: Platzhalter (?) können ausschließlich für Datenwerte genutzt werden, nicht für Tabellen- oder Spaltennamen. Diese müssen bei dynamischen Abfragen manuell validiert und gegen eine Whitelist geprüft werden.

Mehrere Statements: mysqli_prepare() akzeptiert nur eine einzelne SQL-Anweisung. Der Versuch, mehrere Anweisungen durch ; zu trennen, schlägt fehl.

Fehlerbehandlung: Ab PHP 8.1 wirft MySQLi bei Fehlern standardmäßig Exceptions (mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT) ist der neue Standard). Es empfiehlt sich, dieses Verhalten explizit zu aktivieren, um false-Checks zu vermeiden.