utf-8 codierung von DB zum browser fehlerhaft
eager2learn
- datenbank
0 dedlfix0 eager2learn0 dedlfix0 eager2learn0 dedlfix
0 eager2learn0 dedlfix
Für alle, die sich wie ich Stunden des Unglücks mit utf-Codierung rumgequält haben und sich fragen, warum die Daten zwar korrekt in der Datenbank gespeichert, aber fehlerhaft ausgespuckt werden, schaut mal nach, ob Ihr aus früheren Zeiten vielleicht noch htmlentities in der Abfrage verwendet. Die verkorksten bei mir nämlich die ansonsten stringenten utf-Einstellungen wieder. Und bis ich mal auf die Idee kam, es ohne die sonst immer genutzte Funktion zu versuchen, gingen Stunden ins Land. Wenn ihr also eigentlich alles richtig eingestellt habt und es scheitert trotzdem an dem Punkt, einfach mal darauf prüfen.
Vielleicht hilft es dem ein oder anderen ja weiter.
Liebe Grüße
Sam
Hi!
Für alle, die sich wie ich Stunden des Unglücks mit utf-Codierung rumgequält haben und sich fragen, warum die Daten zwar korrekt in der Datenbank gespeichert, aber fehlerhaft ausgespuckt werden, schaut mal nach, ob Ihr aus früheren Zeiten vielleicht noch htmlentities in der Abfrage verwendet. Die verkorksten bei mir nämlich die ansonsten stringenten utf-Einstellungen wieder.
Du müsstest mal das Szenario genauer beschreiben, damit es in Zeichenkodierungsdingen nicht so bewanderte, an die du dich ja richtest, eindeutig mit ihrer Situation vergleichen können. htmlentities() kann man an vielen Stellen falsch einbauen. Wenn du diese Funktion vor der Ausgabe in Richtung HTML drin hattest, so hattest du vermutlich den charset-Parameter vergessen zu setzen, als du von der Default-Kodierung ISO-8859-1 umgestiegen bist. Komplett entfernen solltest du die Funktion nicht, sondern sie gegen htmlspecialchars() austauschen. Zusammen mit der ordnungsgemäßen Angabe des charset-Parameters im HTTP-Header Content-Type und im gleichenamigen Meta-Element ist es ausreichend, nur die HTML-eigenen Zeichen zu beachten (das ist allerdings eine Pflicht-Anforderung, wenn man sicher programmieren möchte).
Lo!
Hi Lo!
ich hatte insbesondere Deine Beiträge zu dem Thema gelesen. In meinem Fall ist es so gewesen, dass ich testweise ein älteres Skript kopiert hatte, in dem htmlentities() eingebaut war. Erst später habe ich mich dann um die anderen Einstellungen gekümmert. Ich hatte die entsprechenden Angaben natürlich im Header:
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
Ich hatte die jeweiligen Einstellungen außerdem in der php.ini für PHP, in der httpd.conf für den Apache-Server und der my.cnf für MYSQL gesetzt.
Desweiteren hatte ich dann entsprechende Angaben in der .htaccess-Datei gemacht:
AddCharset UTF-8 .html .php
Und natürlich war UTF8 für die Datenbank, alle Tabellen und alle Textfelder definiert. Das bestätigte mir zum einen die Ausgabe der Variabeln in phpmyadmin als auch der Test via
mysql_query("SHOW VARIABLES LIKE 'c%'");
zur expliziten Datenbank-Connection. Alles war utf8.
Die Formulare waren für jene Browser, die es unterstützen noch zusätzlich ergänzt mit:
<form action="$PHP_SELF" method="post" enctype="multipart/form-data" accept-charset="utf-8">
Die Eingabe via Formular in Richtung Datenbank funktionierte dann auch einwandfrei, nur das Auslesen hat mich wahnsinnig gemacht. Irgenwann fiel mir dann htmlentities() auf, was ich sonst häufiger für flat-Databases genutzt habe. Als ich es versuchsweise entfernt habe, hat endlich alles einwandfrei geklappt.
Klar, für Quotes und andere Sonderzeichen, die escaped werden müssen, sollte man dann auf htmlspecialchars() zurückgreifen. Aber manchmal sieht man ja vor lauter Bäumen den Wald nicht mehr und deswegen erspart es vielleicht einigen das weitere Suchen...
Liebe Grüße
Sam
Hi!
<form action="$PHP_SELF" method="post" enctype="multipart/form-data" accept-charset="utf-8">
Achte darauf, dass $_SERVER['PHP_SELF'] durch Anhängen eines Querystrings mit allem möglichen gefüllt sein kann. Deshalb muss auch dieser Wert mit htmlspecialchars() behandelt werden. Oder aber, man nimmt action="", das steht ebenfalls für die aktuelle URL, ist einfacher zu notieren und nicht für Injections anfällig.
Die Eingabe via Formular in Richtung Datenbank funktionierte dann auch einwandfrei, nur das Auslesen hat mich wahnsinnig gemacht. Irgenwann fiel mir dann htmlentities() auf, was ich sonst häufiger für flat-Databases genutzt habe. Als ich es versuchsweise entfernt habe, hat endlich alles einwandfrei geklappt.
Du hast meine Vermutung nicht bestätigt/widerlegt. htmlentities() hat einen Parameter zum Angeben der Kodierung (der dritte namens charset) Wenn du den nicht auf #utf-8' stellst, aber UTF-8-kodierte Daten übergibst, dann wird jedes einzelne Byte von UTF-8-Byte-Sequenzen in eine NCR gewandelt. Das müsste auch sehr schön in der Quelltextansicht des Browsers zu sehen sein. Im Text sieht man dann beispielsweise zwei verkorkste Zeichen statt eines Umlauts.
Lo!
Achte darauf, dass $_SERVER['PHP_SELF'] durch Anhängen eines Querystrings mit allem möglichen gefüllt sein kann. Deshalb muss auch dieser Wert mit htmlspecialchars() behandelt werden. Oder aber, man nimmt action="", das steht ebenfalls für die aktuelle URL, ist einfacher zu notieren und nicht für Injections anfällig.
Danke für den Hinweis. Werde ich berücksichtigen.
Du hast meine Vermutung nicht bestätigt/widerlegt. htmlentities() hat einen Parameter zum Angeben der Kodierung (der dritte namens charset) Wenn du den nicht auf #utf-8' stellst, aber UTF-8-kodierte Daten übergibst, dann wird jedes einzelne Byte von UTF-8-Byte-Sequenzen in eine NCR gewandelt. Das müsste auch sehr schön in der Quelltextansicht des Browsers zu sehen sein. Im Text sieht man dann beispielsweise zwei verkorkste Zeichen statt eines Umlauts.
Klingt in etwa wie das, was ich zu sehen bekam. Ich werde es morgen mal probieren und Feedback posten. Gibt es denn eine Notwendigkeit oder Vorteile htmlentities() zu verwenden im Gegensatz zum "plain" htmlspecialchars() da ja sonst alles zu gehen scheint momentan?
Liebe Grüße
Sam
Hi!
Gibt es denn eine Notwendigkeit oder Vorteile htmlentities() zu verwenden im Gegensatz zum "plain" htmlspecialchars() da ja sonst alles zu gehen scheint momentan?
Mit UTF-8 gibt es diese Notwendigkeit nicht. Alle Zeichen können direkt kodiert werden (Ausnahme bilden die Zeichen, um die sich htmlspecialchars() kümmert). Entities oder NCRs benötigt man nur, wenn Zeichen nicht direkt kodiert werden können, beispielsweise das €-Zeichen in ISO-8859-1. 1-Byte-Kodierungen bringen jedoch Probleme mit sich, wenn Browser eingegebene Daten an den Webserver senden wollen. Was sollen sie aus dem € machen? Es ist in keiner Spezifikation festgelegt, wie dann zu verfahren ist (für HTML5 weiß ich das nicht). Manche Browser senden dann ein € (oder dessen NCR). Wie aber soll man auf Serverseite erkennen, ob jemand ein € oder € eingegeben hat, zumal ein eingetipptes & direkt als solches und nicht ebenfalls entitysiert/ncr-isiert wird? Das sind Probleme, die man nicht haben will, und die mit UTF-8 schlichtweg nicht auftreten.
Lo!
Du hast meine Vermutung nicht bestätigt/widerlegt. htmlentities() hat einen Parameter zum Angeben der Kodierung (der dritte namens charset) Wenn du den nicht auf #utf-8' stellst, aber UTF-8-kodierte Daten übergibst, dann wird jedes einzelne Byte von UTF-8-Byte-Sequenzen in eine NCR gewandelt. Das müsste auch sehr schön in der Quelltextansicht des Browsers zu sehen sein. Im Text sieht man dann beispielsweise zwei verkorkste Zeichen statt eines Umlauts.
Wenn ich htmlentities($result["foo"], ENT_QUOTES, "UTF-8");
nutze klappt alles einwandfrei. Danke für den Hinweis :).
Viele Grüße
Sam
Hi!
Wenn ich
htmlentities($result["foo"], ENT_QUOTES, "UTF-8");
nutze klappt alles einwandfrei. Danke für den Hinweis :).
Ja, so berücksichtigt die Funktion die Kodierung, aber - wie gesagt - notwendig und sinnvoll ist für als UTF-8 ausgelieferte Seiten nur htmlspecialchars().
Lo!