PHP, MySQL und der Ärger mit UTF-8
erschienen in der Kategorie Webdesign, am 28.03.2012

Immer wieder liest man im Netz von Problemen mit PHP, MySQL und UTF-8. Der Webserver soll Daten aus der MySQL Datenbank lesen und auf der, in UTF-8 codierten, Webseite darstellen. Trotz der Tatsache, dass die Daten auch in der Datenbank im UTF-8 Format gespeichert sind, werden die Umlaute falsch dargestellt.
Tückisch an diesem Problem ist vor allem auch die Tatsache, dass der Fehler auf dem eigenen Rechner (Lokalhost) oft gar nicht auftritt. So kann es vorkommen, dass man in aller Seelenruhe, auf dem lokal gehosteten Webserver, eine Homepage baut, dann irgendwann glaubt fertig zu sein, und die Seite voller Vorfreude auf den Webspace hochlädt. Dachte man bis eben noch endlich fertig zu sein, wird man nun eines Besseren belehrt und mit bösartigen Fragezeichen, statt Umlauten, beworfen.
Des Fehlers Ursprung begründet sich in der Tatsache, dass die meisten deutschen Provider davon ausgehen, dass ihre ebenfalls deutschen Kunden Webseiten bauen, die mit der ISO-8859-1 Codierung arbeiten. Daher haben sie ihre Web- und Datenbankserver so konfiguriert, dass sie mit dieser Codierung optimal klarkommen.
Zur Fehlerbehebung und vor allem zur Fehlervermeidung (für jene, die nicht auf diese Webseite gestoßen sind, weil sie gerade mit dem beschriebenen Problem kämpfen), sei Folgendes empfohlen: Vor dem ersten Zugriff (Query) auf die Datenbank sollte folgende Codezeile ausgeführt werden:
Dies sorgt dafür, dass der Datenbankserver weiß, dass er sowohl bei Datenbankabfragen als auch bei Inserts oder Updates mit UTF-8-codierten Daten arbeiten soll. Der Befehl muss nicht vor jeder Query ausgeführt werden, es reicht, wenn man ihn vor der Ersten ausführt oder am besten direkt, nachdem man die Datenbankverbindung aufgebaut hat.
In vielen Foren wird, statt dieser Lösung, empfohlen mit den PHP-Funktionen utf8_encode und utf8_decode zu arbeiten, dies halte ich aber für einen ziemlich (wartungs-) aufwendigen Workaround, der das Problem auch nicht wirklich bei der Wurzel packt.
Hier noch ein paar allgemeine Tipps für eine saubere UTF-8 Webseiten-Umsetzung
Tschüssikowski, Fragezeichen des Grauens!
Wer seinen eigenen Webserver betreibt, kann sich die oben genannten Punkte (abgesehen vom HTML-Meta-Tag) sparen, indem er die entsprechenden Einstellungen als Standard festlegt.
Apache-Einstellungen: In der Konfigurationsdatei (in der Regel /etc/apache2/http.conf oder /etc/apache2/apache2.conf) des Apache-Webservers fügt man die folgende Zeile hinzu (oder ändert die Codierung, falls die Zeile schon vorhanden ist):
PHP-Einstellungen: In der Datei php.ini (unter /etc/php5/apache2/ zu finden) ändert man die folgenden Parameter, bzw. fügt sie hinzu, falls noch nicht vorhanden:
Falls vor einem Eintrag noch ein Semikolon steht, muss dieses entfernt werden (sonst ist er auskommentiert).
MySQL-Konfiguration: In der der Datei /etc/mysql/my.cnf fügt man folgende Einstellungen ein:
Das nimmt einem auch das Ausführen der oben gezeigten Query ab. Somit muss man sich bei der Implementierung keine Gedanken mehr um die Codierung machen.
Nachdem die Änderungen vorgenommen wurden, müssen die betreffenden Server neu gestartet werden (# /etc/init.d/apache2 restart, # /etc/init.d/mysql restart).

Des Fehlers Ursprung begründet sich in der Tatsache, dass die meisten deutschen Provider davon ausgehen, dass ihre ebenfalls deutschen Kunden Webseiten bauen, die mit der ISO-8859-1 Codierung arbeiten. Daher haben sie ihre Web- und Datenbankserver so konfiguriert, dass sie mit dieser Codierung optimal klarkommen.
Zur Fehlerbehebung und vor allem zur Fehlervermeidung (für jene, die nicht auf diese Webseite gestoßen sind, weil sie gerade mit dem beschriebenen Problem kämpfen), sei Folgendes empfohlen: Vor dem ersten Zugriff (Query) auf die Datenbank sollte folgende Codezeile ausgeführt werden:
mysqli_query($dbcon, "SET NAMES 'utf8'");
Dies sorgt dafür, dass der Datenbankserver weiß, dass er sowohl bei Datenbankabfragen als auch bei Inserts oder Updates mit UTF-8-codierten Daten arbeiten soll. Der Befehl muss nicht vor jeder Query ausgeführt werden, es reicht, wenn man ihn vor der Ersten ausführt oder am besten direkt, nachdem man die Datenbankverbindung aufgebaut hat.
$dbcon = mysqli_connect($dbhost,$dbuser,$dbpass);
mysqli_select_db($dbcon, $dbname);
mysqli_query($dbcon, "SET NAMES 'utf8'");
...
mysqli_query(...);
...
mysqli_close($dbcon);
mysqli_select_db($dbcon, $dbname);
mysqli_query($dbcon, "SET NAMES 'utf8'");
...
mysqli_query(...);
...
mysqli_close($dbcon);
In vielen Foren wird, statt dieser Lösung, empfohlen mit den PHP-Funktionen utf8_encode und utf8_decode zu arbeiten, dies halte ich aber für einen ziemlich (wartungs-) aufwendigen Workaround, der das Problem auch nicht wirklich bei der Wurzel packt.
Hier noch ein paar allgemeine Tipps für eine saubere UTF-8 Webseiten-Umsetzung
- im HTML Head Bereich angeben, dass die Seite UTF-8 kodiert ist:
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> - im PHP Header ebenfalls:
header("Content-Type: text/html; charset=utf-8"); - alle PHP Dateien UTF-8 kodiert abspeichern
Tschüssikowski, Fragezeichen des Grauens!
UTF-8 Server-Einstellungen
Update 05.02.2014: Weil diesbezüglich gerade eine Frage per Mail rein kam, hier noch ein paar Infos zur Linux-Server-Konfiguration:Wer seinen eigenen Webserver betreibt, kann sich die oben genannten Punkte (abgesehen vom HTML-Meta-Tag) sparen, indem er die entsprechenden Einstellungen als Standard festlegt.
Apache-Einstellungen: In der Konfigurationsdatei (in der Regel /etc/apache2/http.conf oder /etc/apache2/apache2.conf) des Apache-Webservers fügt man die folgende Zeile hinzu (oder ändert die Codierung, falls die Zeile schon vorhanden ist):
AddDefaultCharset UTF-8
PHP-Einstellungen: In der Datei php.ini (unter /etc/php5/apache2/ zu finden) ändert man die folgenden Parameter, bzw. fügt sie hinzu, falls noch nicht vorhanden:
default_charset = "UTF-8"
[iconv]
iconv.input_encoding = UTF-8
iconv.internal_encoding = UTF-8
iconv.output_encoding = UTF-8
[exif]
exif.encode_unicode = UTF-8
[mssql]
mssql.charset = "UTF-8"
[iconv]
iconv.input_encoding = UTF-8
iconv.internal_encoding = UTF-8
iconv.output_encoding = UTF-8
[exif]
exif.encode_unicode = UTF-8
[mssql]
mssql.charset = "UTF-8"
Falls vor einem Eintrag noch ein Semikolon steht, muss dieses entfernt werden (sonst ist er auskommentiert).
MySQL-Konfiguration: In der der Datei /etc/mysql/my.cnf fügt man folgende Einstellungen ein:
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
[mysqld]
collation-server = utf8_general_ci
init-connect='SET NAMES utf8'
character-set-server = utf8
default-character-set=utf8
[mysql]
default-character-set=utf8
[mysqld]
collation-server = utf8_general_ci
init-connect='SET NAMES utf8'
character-set-server = utf8
Das nimmt einem auch das Ausführen der oben gezeigten Query ab. Somit muss man sich bei der Implementierung keine Gedanken mehr um die Codierung machen.
Nachdem die Änderungen vorgenommen wurden, müssen die betreffenden Server neu gestartet werden (# /etc/init.d/apache2 restart, # /etc/init.d/mysql restart).
Geschnatter
60 Kommentare, selbst mitschnattern
thebigsmileXD, am 08.10.2014 um 20:00 Uhr
Vielen Danke Euch!!!
Nachdem ich (nach 1 Jahr und 580 Datenbankeinträgen) endlich gemerkt habe, dass in meiner Datenbank alle Umlaute komisch aussehen, habe ich das Charset der DB auf utf-8 gestellt. Damit sah es in der DB toll aus, allerdings war das Output mit "?" durchmengt.
Dank Euch habe ich jetzt mysqli->set_charset("utf8"); hinzugefügt und siehe da: Schreiben UND Lesen sind supi!
DAANKEE ;D
Nachdem ich (nach 1 Jahr und 580 Datenbankeinträgen) endlich gemerkt habe, dass in meiner Datenbank alle Umlaute komisch aussehen, habe ich das Charset der DB auf utf-8 gestellt. Damit sah es in der DB toll aus, allerdings war das Output mit "?" durchmengt.
Dank Euch habe ich jetzt mysqli->set_charset("utf8"); hinzugefügt und siehe da: Schreiben UND Lesen sind supi!
DAANKEE ;D
Bvz, am 17.10.2014 um 13:54 Uhr
Guter Artikel, probier ich zu Hause mal aus.
Tilly Dö, am 08.11.2014 um 21:08 Uhr
Seit Jahren kenne ich dieses Problem und nun auch die Lösung. Vielen Dank dafür!
Anonym, am 30.11.2014 um 18:26 Uhr
DANKE!!! Ich stand einen Meter vor dem Nervenzusammenbruch!
codingNexus_, am 07.12.2014 um 04:11 Uhr
big thx.
komischerweise hat es bei einem Tutorial gepasst. Als ich aber angefangen hab meine eigene Seite zu bauen kam dann dieser Fehler.
Aber das hier hat sehr geholfen (:)
komischerweise hat es bei einem Tutorial gepasst. Als ich aber angefangen hab meine eigene Seite zu bauen kam dann dieser Fehler.
Aber das hier hat sehr geholfen (:)
Matthias, am 18.12.2014 um 04:21 Uhr
Vielen Vielen Vielen Dank für dies wundervollen Thread...hat mir weitere Stunden Fehlersuche erspart...Nice Work! Weiter so!!
Sxxx, am 22.03.2015 um 15:32 Uhr
Danke!!!! Hast mir gerade stundenlange Arbeit erspart :)
Es gelten die Regelungen der Datenschutzerklärung.