Mal wieder Zeichensätze
heinetz
- php
Hallo Forum,
ich möchte mit den Daten aus einem HTML-Form eine XML schreiben.
Und zwar mit UTF-8. Die Seite mit dem Form ist nun kiene UTF-8
Seite und lässt sich auch nicht als sollche definieren. Unter
Mozilla läuft das ganze seit dem ich im Form
accept-charset="utf-8" geschrieben habe. Mit dem IE allerdings
nicht ;(
Da meckert beim Auslesen php einen Parser-Error an, weil lauter
ü und ö unmaskiert in der XML stehen.
Wie mache ich aus einem 'ö' in $_POST ein 'ö'. Das mag der
XML-Parser nämlich leiden.
danke für Tipps und
beste gruesse,
heinetz
Moin!
ich möchte mit den Daten aus einem HTML-Form eine XML schreiben.
Und zwar mit UTF-8. Die Seite mit dem Form ist nun kiene UTF-8
Seite und lässt sich auch nicht als sollche definieren.
Doch, das muss gehen, alles andere führt nur in die Irre und sorgt für Datenverlust-
Unter
Mozilla läuft das ganze seit dem ich im Form
accept-charset="utf-8" geschrieben habe. Mit dem IE allerdings
nicht ;(
accept-charset ist ganz großer Mist, weil die Browser sich nicht dran halten. Diese Lösung kannst du direkt wieder vergessen.
Alles muss UTF-8 sein, nur dann funktioniert es: Die Seite mit dem Formular, die Charset-Definition im HTTP-Header, die Charset-Angabe im <meta>, und dann gerne auch noch accept-charset.
Wenn irgendwas davon nicht UTF-8 ist, funktioniert es nicht.
Da meckert beim Auslesen php einen Parser-Error an, weil lauter
ü und ö unmaskiert in der XML stehen.
Unmaskiert ist nicht das Problem. Sie sind aber falsch codiert - das ist das Problem.
Wie mache ich aus einem 'ö' in $_POST ein 'ö'. Das mag der
XML-Parser nämlich leiden.
Du hast kein "ö", sondern du hast ein "ö" als ISO-8859-1, brauchst aber eines in UTF-8. Es führt aber zu keiner Lösung, wenn du das jetzt im IE umcodierst, denn du kannst dich einfach nicht drauf verlassen, dass nicht irgendein Browser noch auf ganz andere Codierungsideen kommt - und du kannst auch nicht mit 100% Sicherheit erkennen, welche Codierung der Browser denn verwendet.
Beseitige das Problem an der Wurzel: Liefere die Formularseite UTF-8-codiert aus!
- Sven Rautenberg
Moin!
Beseitige das Problem an der Wurzel: Liefere die Formularseite UTF-8-codiert aus!
Details: Does accept-charset help in HTML forms?
Short answer: No.
Die dort aufgeführte Tabelle sollte abschreckend genug sein!
- Sven Rautenberg
Moin!,
ich möchte Dir ja beipflichten, aber das Problem an der
Wurzel zu packen und alles auf utf-8 umzustellen ist
leider zu diesem Zeitpunkt definitiv nicht drin. Es muss
doch möglich sein, das ganze php-seitig umzukodieren!
gruesse,
heinetz
Moin!
ich möchte Dir ja beipflichten, aber das Problem an der
Wurzel zu packen und alles auf utf-8 umzustellen ist
leider zu diesem Zeitpunkt definitiv nicht drin. Es muss
doch möglich sein, das ganze php-seitig umzukodieren!
Wenn du das Encoding der Seite nicht umstellen kannst, dann bist du gezwungen, das Encoding des Formulars ebenfalls unverändert zu belassen.
Das wiederum bedeutet, dass du Zeichen, die sich in dem derzeitigen Encoding nicht darstellen lassen, in jedem Fall zerstört werden.
Den unzerstörten Rest kannst du dann in PHP vom Seitenencoding in UTF-8 umcodieren und in XML speichern. Alternativ könntest du das XML auch direkt im Encoding der Seite lassen, denn vermutlich ist es bei dem Projekt insgesamt schlauer, auf Encoding-Monokultur zu setzen. XML benötigt UTF-8 ja nicht zwingend - und die Zeichen, die im derzeitigen Seiten-Encoding nicht darstellbar sind, sind ja sowieso zerstört.
- Sven Rautenberg
Moin!
das alles ist ziemlich komplex:
Ich habe auf dem Frontend der Site einen Flash-Videoplayer
eingebaut. Dieser Videoplayer includiert ein TimedText-XML,
in dem die Untertitel stehen. Darin ist z.B. ein 'ü' als
'ü' maskiert.
Für das Backend habe ich eine Pflegemöglichkeit dieser
Untertitle gebaut:
Aus dem XML wird zunächst ein SimpleXML-Object gebildet
und mit den Werten daraus wird dann ein JS-Array in den
Quellcode geschrieben. Dort steht dann schon 'ü' statt
'ü'. Aus diesem JS-Array wird dann onload per JS
ein Form mit input-Feldern und den Werten aus dem JS-Array
geschrieben.
Wenn dann das Form abgeschickt wird, wird ein neues XML mit
den Werten aus diesem Form geschrieben.
Wenn ich dann das geschriebene XML erneut auf dem beschriebenen
Web einlese, sind die Umlaute im A****.
Jetzt frage ich mich, an welcher Stelle gehen Sie kaputt
gehen.
gruesse,
heinetz
Moin!
das alles ist ziemlich komplex:
War zu befürchten. Deshalb: Encoding-Monokultur, nicht wild wechseln oder umcodieren. Dann geht am wenigsten kaputt. Gegen kaputte Komponenten, die hergestellt wurden von Menschen, die das Prinzip nicht verstanden haben, hilft das allerdings nur bedingt.
Ich habe auf dem Frontend der Site einen Flash-Videoplayer
eingebaut. Dieser Videoplayer includiert ein TimedText-XML,
in dem die Untertitel stehen. Darin ist z.B. ein 'ü' als
'ü' maskiert.
Das ist ja aber nur Lesezugriff auf die Information.
Die Maskierung hat nichts mit UTF-8 zu tun. Die angegebene Zahl ist zwar der Unicode-Codepoint (in dezimaler Schreibweise), aber die eigentlich interessante Frage ist, ob diese Schreibweise wirklich zwingend ist, oder ob ein entsprechend markiertes XML-File ohne diese numerische Zeichenreferenz vom XML-Parser in Flash auch verstanden wird. Dazu muss das XML allerdings korrekt angeben, welches Encoding verwendet wird.
Für das Backend habe ich eine Pflegemöglichkeit dieser
Untertitle gebaut:Aus dem XML wird zunächst ein SimpleXML-Object gebildet
und mit den Werten daraus wird dann ein JS-Array in den
Quellcode geschrieben. Dort steht dann schon 'ü' statt
'ü'.
Das ist logisch. Die Schreibweise als numerische Zeichenreferenz wird vom XML-Parser aufgelöst in eine interne Speicherdarstellung des damit gemeinten Zeichens. Welche Form der Speicherung dabei verwendet wird, ist in erster Näherung erstmal irrelevant, solange die Info "intern" bleibt. Interessant wird es aber genau dann, wenn dieser interne Text über ein Interface des XML-Parsers nach außen weitergegeben wird.
In dem Moment, wo du den String also aus SimpleXML abgreifst, ist relevant, welches Encoding vorliegt. Außerdem ist relevant, wie dieses Encoding dann in das Javascript-Array getan wird, und auf welche Weise das JS-Array ausgeliefert wird.
Aus diesem JS-Array wird dann onload per JS
ein Form mit input-Feldern und den Werten aus dem JS-Array
geschrieben.
Im Browser und in Javascript ist alles Unicode, egal welches Encoding verwendet wurde, denn der Browser wandelt basierend auf der Encoding-Angabe alle erhaltenen Zeichen sowie auch alle Entities (ä) und numerischen Zeichenreferenzen (ü) in eine interne Speicherdarstellung für Unicode-Zeichen.
Wenn dann das Form abgeschickt wird, wird ein neues XML mit
den Werten aus diesem Form geschrieben.
Zu diesem Zeitpunkt wandelt der Browser die eingegebenen Zeichen in das Encoding der Seite (wenn Zeichen eingegeben wurden, die nicht im Encoding darstellbar sind, gehen sie dabei auf unterschiedliche Weise, je nach Browser, kaputt) und steckt sie in den POST- (oder auch GET-)Request.
Wenn ich dann das geschriebene XML erneut auf dem beschriebenen
Web einlese, sind die Umlaute im A****.
Beim Schreiben des XML muss natürlich das Encoding wieder beachtet werden.
Jetzt frage ich mich, an welcher Stelle gehen Sie kaputt
gehen.
Du hast an jeder Stelle, wo das Schriftzeichen den Zustand wechselst, ein potentielles Verlustrisiko.
- Sven Rautenberg
Moin!
»» das alles ist ziemlich komplex:
War zu befürchten. Deshalb: Encoding-Monokultur, nicht wild wechseln oder umcodieren. Dann geht am wenigsten kaputt. Gegen kaputte Komponenten, die hergestellt wurden von Menschen, die das Prinzip nicht verstanden haben, hilft das allerdings nur bedingt.
»» Ich habe auf dem Frontend der Site einen Flash-Videoplayer
»» eingebaut. Dieser Videoplayer includiert ein TimedText-XML,
»» in dem die Untertitel stehen. Darin ist z.B. ein 'ü' als
»» 'ü' maskiert.Das ist ja aber nur Lesezugriff auf die Information.
Die Maskierung hat nichts mit UTF-8 zu tun. Die angegebene Zahl ist zwar der Unicode-Codepoint (in dezimaler Schreibweise), aber die eigentlich interessante Frage ist, ob diese Schreibweise wirklich zwingend ist, oder ob ein entsprechend markiertes XML-File ohne diese numerische Zeichenreferenz vom XML-Parser in Flash auch verstanden wird. Dazu muss das XML allerdings korrekt angeben, welches Encoding verwendet wird.
OK, ich versuche neu anzufangen, die Maskierungen im xml
entfernt, "<?xml version="1.0" encoding="UTF-8"?>" in der
ersten Zeile eingefügt und es als utf-8 kodiert abgespeichert.
Soweit sogut, wenn die xml nicht etwa aus dem cache geholt
wird, stellt der flashplayer im Frontend (Darin ist UTF-8
als Zeichensatz angegeben) alle Zeichen richtig dar. OK
»» Für das Backend habe ich eine Pflegemöglichkeit dieser
»» Untertitle gebaut:
»»
»» Aus dem XML wird zunächst ein SimpleXML-Object gebildet
»» und mit den Werten daraus wird dann ein JS-Array in den
»» Quellcode geschrieben. Dort steht dann schon 'ü' statt
»» 'ü'.Das ist logisch. Die Schreibweise als numerische Zeichenreferenz wird vom XML-Parser aufgelöst in eine interne Speicherdarstellung des damit gemeinten Zeichens. Welche Form der Speicherung dabei verwendet wird, ist in erster Näherung erstmal irrelevant, solange die Info "intern" bleibt. Interessant wird es aber genau dann, wenn dieser interne Text über ein Interface des XML-Parsers nach außen weitergegeben wird.
Im Backend, wo der Videoplayer auch angezeigt wird, werden
die Sonderzeichen im XML von Flash auch richtig dargestellt.
Die selben Daten durch PHP:simpleXML geparsed und auf der
(nicht UTF-8) Seite in das JS-Array geschrieben und dann
in Input-Felder geschrieben, werden in diesen mit kaputten
Sonderzeichen ausgegeben. Richtig stellen kann ich das,
indem ich vor der Ausgabe PHP:utf8_decode darauf anwende.
Das dürfte in dem Kontext richtig sein, oder ?
Und danach wird es interessant:
Ich rufe durch Abschicken des (POST) Forms ein PHP-Script
auf, dass eine neue Datei (UTF-8-encodiert) anlegen und
die Daten aus POST UTF-8-encodiert dort hineinschreiben
soll.
Das POST-Array vor dem Schreiben mit utf8_encode umzuwandeln
hat geholfen. Das funktioniert also scheinbar.
Jetzt gibt es aber noch einen neuen Fallstrick:
Ich lese das XML im Backend nicht direkt ein, sondert kopiere
es vorher als temp.xml und lese dann das ein. Folgender
Hintergrund:
Beim Abschicken des Formulars wird ein PHP-Skript aufgerufen,
dass das Original.xml mit den Werten aus den Formularfeldern
überschreibt. Zusätzlich habe ich eine Funktionalität gebaut,
die diese Daten nicht durch Abschicken des Formulars, sondern
über einen Ajax.Request an das selbe Skript schickt, dass dann
aber nicht das Original.xml, sondern dass temp.xml schreibt.
So lassen sich die Eingaben testen.
Der einzige Unterschied, den ich mir zwischen dem Abschicken des
Formulars und dem Ajax.Request vorstellen kann, ist, dass der
Absender ein Andrer ist.
tausend dank und
gruesse,
heinetz
Moin!
»» Deshalb: Encoding-Monokultur, nicht wild wechseln oder umcodieren. Dann geht am wenigsten kaputt.
Das würde ich noch einmal unterstreichen. Wobei deine Konstruktion etwas wild ist wegen des AJAX.
OK, ich versuche neu anzufangen, die Maskierungen im xml
entfernt, "<?xml version="1.0" encoding="UTF-8"?>" in der
ersten Zeile eingefügt und es als utf-8 kodiert abgespeichert.
Das ist ok.
Soweit sogut, wenn die xml nicht etwa aus dem cache geholt
wird, stellt der flashplayer im Frontend (Darin ist UTF-8
als Zeichensatz angegeben) alle Zeichen richtig dar. OK
Und hat Erfolg.
Im Backend, wo der Videoplayer auch angezeigt wird, werden
die Sonderzeichen im XML von Flash auch richtig dargestellt.
Die selben Daten durch PHP:simpleXML geparsed und auf der
(nicht UTF-8) Seite in das JS-Array geschrieben und dann
in Input-Felder geschrieben, werden in diesen mit kaputten
Sonderzeichen ausgegeben. Richtig stellen kann ich das,
indem ich vor der Ausgabe PHP:utf8_decode darauf anwende.Das dürfte in dem Kontext richtig sein, oder ?
So ist es.
Und danach wird es interessant:
Ich rufe durch Abschicken des (POST) Forms ein PHP-Script
auf, dass eine neue Datei (UTF-8-encodiert) anlegen und
die Daten aus POST UTF-8-encodiert dort hineinschreiben
soll.
Die Daten, die aus dem Formular kommen, sind ISO-8859-1...
Das POST-Array vor dem Schreiben mit utf8_encode umzuwandeln
hat geholfen. Das funktioniert also scheinbar.
...weswegen das zwingend notwendig ist, sofern das XML in UTF-8 sein soll.
Jetzt gibt es aber noch einen neuen Fallstrick:
Ich lese das XML im Backend nicht direkt ein, sondert kopiere
es vorher als temp.xml und lese dann das ein. Folgender
Hintergrund:Beim Abschicken des Formulars wird ein PHP-Skript aufgerufen,
dass das Original.xml mit den Werten aus den Formularfeldern
überschreibt. Zusätzlich habe ich eine Funktionalität gebaut,
die diese Daten nicht durch Abschicken des Formulars, sondern
über einen Ajax.Request an das selbe Skript schickt, dass dann
aber nicht das Original.xml, sondern dass temp.xml schreibt.
So lassen sich die Eingaben testen.Der einzige Unterschied, den ich mir zwischen dem Abschicken des
Formulars und dem Ajax.Request vorstellen kann, ist, dass der
Absender ein Andrer ist.
Alles, was in AJAX läuft, ist zwingend UTF-8-codiert. Das gilt sowohl für Requests, als auch für Responses. Man kann versuchen, das Encoding zu beeinflussen, wird dabei aber derartig eklige Krücken sowie böse Browserbugs entdecken, dass es kein Spaß wird, gegen UTF-8 anzuarbeiten.
Deshalb ist es vom Prinzip her doof, dass du einerseite ein ISO-8859-1-codiertes HTML-Formular verarbeitest, andererseits einen UTF-8-codierten AJAX-Request. Das erfordert eine Fallunterscheidung im Code, und führt zu der etwas unschönen Eigenschaft, dass der AJAX-Request via UTF-8 Zeichen senden kann, die im UTF-8-XML auch unterzubringen und vom Flash auslesbar sind, welche aber beim ISO-Formular nicht darstellbar sind und deshalb verloren gehen. Um zumindest den ISO-Darstellungseffekt auch bei AJAX zu haben, musst du den empfangenen String also einmal von UTF-8 nach ISO umcodieren, und dann wieder nach UTF-8 zurückwandeln.
PS: Das Eurozeichen gibt's übrigens in ISO-8859-1 nicht - nur für den Fall, dass du es vermisst.
- Sven Rautenberg
echo $begrüßung;
PS: Das Eurozeichen gibt's übrigens in ISO-8859-1 nicht - nur für den Fall, dass du es vermisst.
Allerdings ist es in Windows-1252 enthalten, was vom Inhalt her betrachtet eine Erweiterung von ISO-8859-1 ist. Meist werden auch die Windows-1252-spezifischen Zeichen, wenn sie in mit ISO-8859-1 deklarierten Dokumenten auftauchen, "richtig" dargestellt. Allerdings sind einige Konvertierungsroutinen deutlich strenger als die Browser und setzen die Windows-1252-spezifischen Zeichen nicht in ihre UTF-8-Pendants um. Man müsste dann im Falle von PHP statt zu utf8_en/decode() zur iconv- oder recode-Extension greifen.
echo "$verabschiedung $name";
Moin,
schön, ich habe das Gefühl, den ganzen Zeichensalat sauber (in meinem
Kontext) hin- und hercodiert und damit aufgeräumt zu haben. Es ist mir
vollkommen klar, dass ich durch konsequnte Einhaltung eines Zeichensatzes
viel weniger Arbeit hätte und das ganze erst dann wirklich sauber ist!
Du hast mir sehr geholfen. Danke !
Alles, was in AJAX läuft, ist zwingend UTF-8-codiert.
... was das Phänomen erklärt:
die von meinem iso-Form abgeschickten POST-Daten werden
vor dem Schreiben mit utf8_encode nach UTF 8 umgewandelt
und dann korrekt geschrieben.
die per Ajax abgeschickten Daten sind schon UTF 8 und
werden dann genauso behandelt, also nochmal nach UTF 8
umgewandelt, was zum Fehler führt.
schoenen dank und
beste gruesse,
heinetz