Mysql / PHP/ UTF-8, Umlaute werden abgeschnitten
Ingo D. Ongemuth
- datenbank
Hallo zusammen,
ich habe hier ein kleines Problem mit UTF, das eigentlich überschaubar scheint. Aber ich komme einfach nicht darauf.
Mal an einem anschaulichen Beispiel:
INSERT INTO posting (
creation,
account_id,
title,
text
)
VALUES (
CURRENT_TIMESTAMP(),
1,
'title_text',
'mühe'
)
Rufe ich diese query manuell über phpmyadmin (2.6.3-pl1) auf, so sieht alles super aus. mache ich das selbe nun über ein mysql_query in meinem PHP-Script, steht statt "mühe" in der Datenbank nur "m".
Seltsam, denn ich habe sowohl die Datenbank, die Tabellen als auch die entsprechenden Spalten auf
utf8_general_ci
gesetzt und führe bevor ich die Query absetze noch ein
SET NAMES 'utf8'
aus. Schreibe ich die Query parallel in eine Datei
$handle = fopen('/tmp/testutf8.txt', 'a');
fwrite($handle, $query . "\n\n");
fclose($handle);
so liest man darin auch genau die Query, die ich oben bereits gepastet habe. Also irgendwo zwischen PHP und MySQL geht was schief. Hat jemand ne Idee?
Sehr verbunden, mit winterlichen Grüssen,
Ingo
Ok, jetzt habe ich noch ein wenig experimentiert und es wird komplizierter (oder etwa einfacher?):
INSERT INTO posting (
creation,
account_id,
title,
text
)
VALUES (
CURRENT_TIMESTAMP(),
1,
'title_text',
'mühe'
)
Die oben sichtbare Query war ja der Ausgangspunkt. Jetzt habe ich vorhin gefudelt: tatsächlich steht da nicht "mühe" sondern eine PHP-Variable, die das Wort enthält. Da ich in meinem Testaufbau die Query sowohl in eine Datei schreibe als auch in MySQL absetze und ich in der Datei dann die Query in genau dieser Form wieder gefunden habe wie sie oben sichtbar ist, bin ich davon ausgegangen, dass die Query auch genauso unverfälscht an MySQL geht. Dem scheint nicht so zu sein.
Ich habe nun nämlich statt der Variable tatsächlich manuell "mühe" in die Query im PHP-Skript eingetragen und ausgeführt - genau so erscheint es dann in der Datenbank, wie erwartet.
Irgendwie wird die Verwirrung größer...
Danke und Grüsse,
Ingo
Ich sprech mal was mit mir selbst, dann komme ich wie von alleine drauf ;-)
Der Witz ist: mein PHP-Script ist kein klassisches Script sondern ein Web Service. Die Daten werden also nicht durch einen Browser verschickt, der entsprechende Header gesetzt hat. Was ich machen muss, um das zu lösen ist folgendes, easy:
$query->query("
INSERT INTO posting (
creation,
account_id,
title,
text
)
VALUES (
CURRENT_TIMESTAMP(),
" . $account_id . ",
'" . addslashes(utf8_encode($title)) . "',
'" . addslashes(utf8_encode($text)) . "'
)");
Also die utf8_encode-Methode auf die Strings anwenden.
Gelöst :)
Schönen Tag noch
Ingo
echo $begrüßung;
Also die utf8_encode-Methode auf die Strings anwenden.
Ja natürlich, wenn du der Datenbank sagst, dass die Kommunikation in UTF8-Kodierung abläuft und du ihr Daten schickst, die nicht UTF8-kodiert sind, ergibt das Fehler.
Du solltest außerdem nicht addslashes() sondern die für MySQL besser geeignetere Methode mysql_real_escape_string() verwenden.
echo "$verabschiedung $name";
Hallo dedlfix,
danke für den Tipp mit mysql_real_escape_string(), ich habe es gerade eingebaut!
Beste Grüsse, Ingo
echo $begrüßung;
Rufe ich diese query manuell über phpmyadmin (2.6.3-pl1) auf, so sieht alles super aus. mache ich das selbe nun über ein mysql_query in meinem PHP-Script, steht statt "mühe" in der Datenbank nur "m".
Bist du sicher dass sich plötzlich der Datenbank-Wert ändert? Vermutlich teilt dein Script dem Browser nicht die richtige Kodierung mit. Es könnte auch sein, dass dein Script ansonsten mit ISO-8859-1 kodierte Daten liefert und du dazwischen die mit UTF-8 kodierten Daten aus der Datenbank ausgibst. Es kann aber auch was ganz anderes sein. (phpMyAdmin hat das Problem vor dem du stehst schon gelöst, deswegen bereitet es auch keine Probleme.)
Du solltest herausfinden, wo du welche Kodierung verwendest, welche Kodierungsangaben in deinen HTML-Dokumenten stehen, welche Kodierungsangabe der Server in den HTTP-Headerzeilen mitsendet (die überschreibt die Angaben in HTML-Dokumenten).
Hilfreich dafür sind Browser-Extensions, die die gesendeten HTTP-Header anzeigen können. Manchmal hilft auch das Umstellen der Zeichenkodierung im Browser, um die Kodierung der Zeichen herauszubekommen.
Wenn nichts hilft, könntest du mit
echo chunk_split(bin2hex('test string'), 2, ' ');
die einzelnen Bytes anschauen, die die Abfrage zurückliefert.
echo "$verabschiedung $name";