Start · Sprachen · PHP · Referenz · mysqli_real_escape_string

mysqli_real_escape_string

Funktion

Maskiert Sonderzeichen in einer Zeichenkette zur sicheren Verwendung in SQL-Anweisungen unter Berücksichtigung des aktuellen Verbindungs-Zeichensatzes.

seit PHP 5.0.0 Kategorie: db

Signatur

mysqli_real_escape_string(mysqli $mysql, string $string): string

Beschreibung

mysqli_real_escape_string() escapet gefährliche Sonderzeichen in einer Zeichenkette, sodass sie gefahrlos in einem SQL-Literal verwendet werden kann. Die Funktion berücksichtigt dabei den aktuellem Zeichensatz der MySQL-Verbindung – was sie zuverlässiger macht als einfache string-Ersetzungen wie addslashes().

Folgende Zeichen werden maskiert: \x00, \n, \r, \, ', " und \x1a (Ctrl+Z). Dadurch wird verhindert, dass Benutzereingaben die Struktur eines SQL-Statements verändern und SQL-Injection-Angriffe ermöglichen.

Wichtig: Die Funktion ist kein vollständiger Ersatz für Prepared Statements. Für neue Anwendungen sollten grundsätzlich parametrisierte Abfragen (mysqli_prepare() bzw. PDO mit Prepared Statements) bevorzugt werden, da diese strukturell sicherer sind und keine korrekte Zeichensatz-Konfiguration voraussetzen.

Die Funktion ist nur sinnvoll, wenn der Verbindungs-Zeichensatz korrekt gesetzt ist – idealerweise via mysqli_set_charset() und nicht via SET NAMES, da letzteres die interne Zeichensatz-Zustandsmaschine der Bibliothek nicht aktualisiert.

Parameter

Name Typ Default Beschreibung
$mysql Pflicht mysqli Eine aktive mysqli-Verbindungsinstanz, wie sie von mysqli_connect() oder new mysqli() zurückgegeben wird.
$string Pflicht string Die zu maskierende Zeichenkette, typischerweise eine Benutzereingabe, die in ein SQL-Statement eingebettet werden soll.

Rückgabewert

Typ
string
Beschreibung
Gibt die maskierte Zeichenkette zurück. Die Rückgabe ist immer ein string – auch wenn die Eingabe leer war. Im Fehlerfall (z. B. ungültige Verbindung) wird false zurückgegeben.

Beispiele

Benutzereingabe sicher in SQL einbetten

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

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

// Zeichensatz explizit setzen – wichtig für korrekte Maskierung
$mysqli->set_charset('utf8mb4');

$benutzereingabe = "O'Reilly \" DROP TABLE users; --";
$safe = mysqli_real_escape_string($mysqli, $benutzereingabe);

$sql = "SELECT * FROM autoren WHERE nachname = '" . $safe . "'";
echo $sql;
// SELECT * FROM autoren WHERE nachname = 'O\'Reilly \" DROP TABLE users; --'

$mysqli->close();
SELECT * FROM autoren WHERE nachname = 'O\'Reilly \" DROP TABLE users; --'

Vergleich mit Prepared Statement (empfohlene Alternative)

<?php
$mysqli = new mysqli('localhost', 'user', 'password', 'testdb');
$mysqli->set_charset('utf8mb4');

$benutzereingabe = "O'Reilly";

// Variante 1: mysqli_real_escape_string (funktioniert, aber fehleranfälliger)
$safe = mysqli_real_escape_string($mysqli, $benutzereingabe);
$sql  = "SELECT * FROM autoren WHERE nachname = '" . $safe . "'";
$mysqli->query($sql);

// Variante 2: Prepared Statement (empfohlen)
$stmt = $mysqli->prepare('SELECT * FROM autoren WHERE nachname = ?');
$stmt->bind_param('s', $benutzereingabe);
$stmt->execute();
$result = $stmt->get_result();

while ($row = $result->fetch_assoc()) {
    echo $row['nachname'] . PHP_EOL;
}

$stmt->close();
$mysqli->close();

// Wichtig · Fallstricke

Sicherheitshinweis: mysqli_real_escape_string() schützt nur dann zuverlässig vor SQL-Injection, wenn der Verbindungs-Zeichensatz korrekt über mysqli_set_charset() gesetzt wurde. Wird SET NAMES utf8 via query() ausgeführt, kennt die Client-Bibliothek den neuen Zeichensatz nicht, was bei bestimmten Multibyte-Encodings (z. B. GBK) zu Bypass-Angriffen führen kann.

Prepared Statements bevorzugen: Für neuen Code sollten stets parametrisierte Abfragen mit mysqli_prepare() oder PDO verwendet werden. Sie sind unabhängig vom Zeichensatz strukturell sicher, klarer lesbar und oft auch performanter bei wiederholten Ausführungen.

Kontext beachten: Die Funktion maskiert nur für den Einsatz innerhalb von SQL-String-Literalen. Sie schützt nicht gegen unsichere Verwendung in anderen SQL-Kontexten, z. B. bei dynamischen Tabellen- oder Spaltennamen.