Start · Sprachen · PHP · Referenz · mysql_set_charset

mysql_set_charset

Funktion

Setzt den Zeichensatz (Character Set) für eine aktive MySQL-Verbindung und ist die empfohlene Methode zur Vermeidung von Zeichensatz-bedingten SQL-Injection-Lücken.

seit PHP 5.2.3 Kategorie: db

Signatur

mysql_set_charset(string $charset, resource $link_identifier = NULL): bool

Beschreibung

mysql_set_charset() setzt den Zeichensatz, der für die Kommunikation zwischen Client und MySQL-Server verwendet wird. Die Funktion entspricht dem Aufruf SET NAMES, geht jedoch einen Schritt weiter: Sie teilt dem MySQL-Client-API intern mit, welcher Zeichensatz aktiv ist, sodass Escaping-Funktionen wie mysql_real_escape_string() korrekt arbeiten.

Das explizite Setzen des Verbindungszeichensatzes ist aus Sicherheitsgründen essenziell. Wenn der Zeichensatz nicht explizit gesetzt wird und stattdessen per SET NAMES gesetzt wurde, weiß die MySQL-Client-Bibliothek nicht davon — mysql_real_escape_string() könnte dann unter bestimmten Multi-Byte-Zeichensätzen (z. B. GBK) unsicher sein und SQL-Injection ermöglichen.

Die Funktion sollte direkt nach dem Verbindungsaufbau aufgerufen werden, bevor irgendwelche Abfragen gesendet werden. Der Zeichensatz muss auf dem MySQL-Server verfügbar sein; gültige Zeichensätze können mit der SQL-Abfrage SHOW CHARACTER SET ermittelt werden.

Hinweis: Die gesamte mysql_*-Erweiterung ist seit PHP 5.5.0 veraltet (deprecated) und wurde mit PHP 7.0.0 vollständig entfernt. Es wird dringend empfohlen, auf mysqli oder PDO_MySQL umzusteigen, die eigene Äquivalente bereitstellen.

Parameter

Name Typ Default Beschreibung
$charset Pflicht string Der Name des gewünschten Zeichensatzes, z. B. utf8 oder latin1. Der Zeichensatz muss auf dem MySQL-Server vorhanden sein.
$link_identifier resource NULL Die MySQL-Verbindungsressource, die von mysql_connect() zurückgegeben wurde. Wird dieser Parameter weggelassen, wird die zuletzt geöffnete Verbindung verwendet. Ist keine Verbindung offen, wird versucht, eine neue mit den Standardparametern aufzubauen.

Rückgabewert

Typ
bool
Beschreibung
Gibt true bei Erfolg zurück, false bei einem Fehler (z. B. wenn der Zeichensatz auf dem Server nicht bekannt ist oder keine gültige Verbindung existiert).

Beispiele

Zeichensatz nach Verbindungsaufbau setzen

<?php
$link = mysql_connect('localhost', 'db_user', 'db_password');
if (!$link) {
    die('Verbindung fehlgeschlagen: ' . mysql_error());
}

// Zeichensatz auf UTF-8 setzen – MUSS vor mysql_real_escape_string() erfolgen
if (!mysql_set_charset('utf8', $link)) {
    die('Fehler beim Setzen des Zeichensatzes: ' . mysql_error());
}

$db = mysql_select_db('meine_datenbank', $link);

$benutzereingabe = "O'Reilly & Co";
$sicher = mysql_real_escape_string($benutzereingabe, $link);
$sql = "SELECT * FROM autoren WHERE name = '$sicher'";
$result = mysql_query($sql, $link);

echo 'Abfrage ausgeführt: ' . $sql;
?>
Abfrage ausgeführt: SELECT * FROM autoren WHERE name = 'O\'Reilly & Co'

Prüfung des aktuellen Zeichensatzes vor und nach dem Setzen

<?php
$link = mysql_connect('localhost', 'db_user', 'db_password');

// Aktuellen Zeichensatz ermitteln
$result = mysql_query('SELECT @@character_set_connection AS charset', $link);
$row = mysql_fetch_assoc($result);
echo 'Vor dem Setzen: ' . $row['charset'] . PHP_EOL;

// Zeichensatz auf UTF-8 umstellen
mysql_set_charset('utf8', $link);

$result = mysql_query('SELECT @@character_set_connection AS charset', $link);
$row = mysql_fetch_assoc($result);
echo 'Nach dem Setzen: ' . $row['charset'] . PHP_EOL;

mysql_close($link);
?>
Vor dem Setzen: latin1 Nach dem Setzen: utf8

// Wichtig · Fallstricke

Sicherheit: Verwende niemals SET NAMES als SQL-Abfrage als Ersatz für mysql_set_charset(). Ein SET NAMES-Statement ändert zwar den serverseitigen Zeichensatz, aktualisiert aber nicht den internen Zustand der PHP-Client-Bibliothek. Dadurch kann mysql_real_escape_string() bei Multi-Byte-Zeichensätzen wie GBK oder BIG5 SQL-Injection-anfällig werden.

Deprecation / Entfernung: Die gesamte ext/mysql-Erweiterung wurde in PHP 5.5.0 als veraltet markiert und in PHP 7.0.0 entfernt. Für neue Projekte sollte ausschließlich mysqli_set_charset() oder PDO mit dem DSN-Parameter charset=utf8mb4 verwendet werden.

UTF-8 in MySQL: Für vollständige Unicode-Unterstützung (inkl. Emoji und seltener Zeichen) sollte utf8mb4 anstelle von utf8 verwendet werden, da MySQLs utf8 nur 3-Byte-Zeichen unterstützt.