UTF8, latin1 und Co
Basti2
- html
Hallo,
ich habe zu den Zeichensätzen in HTML, sowie mysql5 einige Fragen.
Wenn ich in meinem Blog keinen Zeichensatz angebe, kann dann ein User durch fehlerhafte Browsereinstellungen Umlautfehler im Blog produzieren, die auch so in die db eingetragen werden?
Dieselbe Frage wie 1, nur mit dem Unterschied, dass ich explizit die Zeichenkodierung über den http-header oder einen metatag angebe?
Kann ich auf der Webseite Kodierung utf-8 angeben und in mysql dennoch mit voreingestelltem latin-1 arbeiten oder ist das nicht fehlerfrei machbar?
Wie stelltz man eine latin-1 DB auf utf-8 um?
Grüße ans Forum,
Basti
Hi!
ich habe zu den Zeichensätzen in HTML, sowie mysql5 einige Fragen.
Du meinst Zeichenkodierung, auch wenn das Ding meist fälschlicherweise als "charset" anzugeben ist.
- Wenn ich in meinem Blog keinen Zeichensatz angebe, kann dann ein User durch fehlerhafte Browsereinstellungen Umlautfehler im Blog produzieren, die auch so in die db eingetragen werden?
Wenn ich dir einen Text geben und nicht sage, in welcher Sprache er geschrieben ist, was kannst du dann logischerweise nur tun? Raten. Was erwartest du dann als Antwort vom Browser, wenn er versucht dir in der erratenen Sprache (um beim Vergleich zu bleiben) zu antworten? Vielleicht passt es, vielleicht nicht.
- Dieselbe Frage wie 1, nur mit dem Unterschied, dass ich explizit die Zeichenkodierung über den http-header oder einen metatag angebe?
Dann hast du und der Browser Gewissheit.
- Kann ich auf der Webseite Kodierung utf-8 angeben und in mysql dennoch mit voreingestelltem latin-1 arbeiten oder ist das nicht fehlerfrei machbar?
Es ist nicht verlustfrei konvertierbar. Es sei denn, du sagt MySQL, dein UTF-8-kodiertes Zeug käme als Latin1 (ISO-8859-1), dann sieht alles in Ordnung aus, aber MySQL hat es falsch im Bauch und kann damit nicht ganz richtig arbeiten (Zeichen zählen, sortieren). Außerdem zeigen dann Tools, die alles richtig machen, wie der phpMyAdmin, falsches Zeug an.
- Wie stelltz man eine latin-1 DB auf utf-8 um?
Es kommt auf die Kodierung der einzelnen Felder an. Wenn die Daten darin richtig kodiert sind (phpMyAdmin zeigt alles richtig an) dann kannst du einfach den Wert für die Kollation ändern. MySQL kodiert dann ordnungsgemäß um.
Lo!
Hi dedlfix,
Du meinst Zeichenkodierung, auch wenn das Ding meist fälschlicherweise als "charset" anzugeben ist.
Ja, genau die meine ich.
Dann hast du und der Browser Gewissheit.
Was ja aber nicnht heißt, dass ein User sienen Browser trotzdem auf eine andere Zeichekodierung einstellt, oder?
- Wie stelltz man eine latin-1 DB auf utf-8 um?
Es kommt auf die Kodierung der einzelnen Felder an. Wenn die Daten darin richtig kodiert sind (phpMyAdmin zeigt alles richtig an) dann kannst du einfach den Wert für die Kollation ändern. MySQL kodiert dann ordnungsgemäß um.
Die einzelnen Felder sind alle durch die Bank nach folgendem Schema aufgebaut:
int steht nichts dahinter,
decimal auch nicht,
timestamp nichts,
char, varchar oder text sind latin1_germany1_ci
Beispieltabelle:
CREATE TABLE db_error (
ErrorID int(6) NOT NULL auto_increment,
ErrorSite varchar(100) collate latin1_german1_ci NOT NULL default '',
ErrorStatus varchar(25) collate latin1_german1_ci NOT NULL default '0',
ErrorURL varchar(255) collate latin1_german1_ci NOT NULL default '',
Datum timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
`query` text collate latin1_german1_ci,
PRIMARY KEY (ErrorID)
) ENGINE=MyISAM AUTO_INCREMENT=136 DEFAULT CHARSET=latin1 COLLATE=latin1_german1_ci;
# --------------------------------------------------------
In welcher Reihenfolge gehe ich nun vor, wenn ich absolut alles auf UTF-8 umstellen möchte?
Und zu Punkt 3: Alle meine php-Dateien müssen ja auch auf UTF-8-Zeichenkodierung gespeichert werden.
Gibt es da ein Programm, was mir dabei hilft? Denn ich habe da etliche Dateien, die ich öffnen, speichern und wieder schließen müsste.
Gruß, Basti
Hi!
Was ja aber nicnht heißt, dass ein User sienen Browser trotzdem auf eine andere Zeichekodierung einstellt, oder?
Was hat er dann davon? Sabotieren kann immer jemand. Wenn jemand Mist machen will, hat er noch ganz andere Möglichkeiten als eine andere Zeichenkodierung zu verwenden. Vermutlich wird nur eine verschwindend geringer Teil seinen Browser unwissentlich falsch einstellen.
Die einzelnen Felder sind alle durch die Bank nach folgendem Schema aufgebaut:
int steht nichts dahinter,
decimal auch nicht,
timestamp nichts,
Die sind ja auch nicht von der Zeichenkodierung betroffen, weil es Zahlen und Zeitwerte sind.
char, varchar oder text sind latin1_germany1_ci
Passt denn der Inhalt zur Angabe? Zeigt phpMyAdmin alles (die Umlaute vor allem) richtig an?
In welcher Reihenfolge gehe ich nun vor, wenn ich absolut alles auf UTF-8 umstellen möchte?
1. Datensicherung.
2. Datenbankinhalt umkodieren, also jedes einzelne String-Feld. Wenn es nicht zu viele sind, mach es zu Fuß, ansonsten lass dir ALTER-TABLE-Statements erstellen. Zusätzlich kannst du noch die Angabe der Tabelle und die der Datenbank umstellen. Diese beiden Angaben sind nur dann wichtig, wenn du neue Felder beziehungsweise Tabellen erstellen willst und dabei keine Kollation/Kodierung angibst, denn dann wird die übergeordnete verwendet.
Bis hier hin kannst du alles mit dem phpMyAdmin machen oder kontrollieren. Den Teilweg zwischen DBMS und PHP kannst du schlecht prüfen, weil du zwecks Ausgabe üblicherweise den Teilweg zwischen PHP/Webserver und dem Browser benötigst.
3. Wenn du mit MySQL kommunizieren willst, müsst du festlegen, welche Kodierung dabei zu verwenden ist. Egal, wie die Daten in den Feldern kodiert sind, es zählt immer die für die jeweilige Verbindung eingestellte Kodierung. Bei Unterschieden kodiert MySQL selbständig um. Also, nach jedem mysql_connect (oder wenn du mysqli verwendest dessen Äquivalent) rufst du mysql_set_charset('utf8') auf (zum Nachlesen).
Ich kann die mysql-Konfiguration selber nicht beeinflussen, da sie beim Provider liegt.
Der legt nur die Default-Werte fest. Alles andere kannst du problemlos überschreiben. Im Falle der Verbindungskodierung solltest du das auch, denn wenn du dich auf den Defaultwert verlässt und sich dieser (warum auch immer) ändert, ...
4. Richtung Browser
- header?
- meta tag?
5. PHP-Code-Dateien müssen nicht zwangsläufig bearbeitet werden. Wenn du nur Code drin stehen hast, betrifft eine Umkodierung potentiell nur Kommentare. (In den Bezeichnern wirst du vermutlich nur ASCII-Zeichen verwendet haben, auch wenn Umlaute etc. erlaubt sind.) Wenn Texte enthalten sind, dann ergibt eine Konvertierung nur dann ein anderes Ergebnis, wenn Nicht-ASCII-Zeichen verwendet wurden - also alles jenseits von a-zA-Z0-9 und ein paar Satzzeichen.
6. PHP-Code. Wenn du die Daten nur vom DBMS zum Browser und wieder zurück durchreichst, ohne Stringverarbeitung anzuwenden, dann brauchst du nichts weiter zu machen. Ansonsten musst du schauen, dass du multibyte-fähige Funktionen findest und verwendest oder prüfen, ob die Funktion eine Kodierungsangabe als optionalen Parameter auswertet. htmlspecialchars() kannst du einfach so aufrufen, denn die von ihr behandelten Zeichen sind alle im ASCII-Bereich. Den Rest lässt diese Funktion unberührt. htmlentities() solltest du jedoch gegen htmlspecialchars() tauschen.
- was sonst noch?
Welche Komponenten sind an deinem Projekt noch beteiligt? Textdateien? Dateinamen? Andere Server? Mailversand?
Der Grundsatz lautet: Jeder beteiligte Prozess muss mit der Kodierung umgehen können - zwischen zwei Prozessen muss die zu verwendende Kodierung ausgehandelt werden, beziehungsweise dem Zielprozess muss sie mitgeteilt werden.
Und zu Punkt 3: Alle meine php-Dateien müssen ja auch auf UTF-8-Zeichenkodierung gespeichert werden.
Gibt es da ein Programm, was mir dabei hilft? Denn ich habe da etliche Dateien, die ich öffnen, speichern und wieder schließen müsste.
Die reine Konvertierung von Dateien geht beispielsweise mit iconv. Das ist ein Unix-Programm. Eine Windows-Version ist auf alle Fälle in Cygwin enthalten. Ob es weitere Massentools gibt, weiß ich nicht. (recode unter Linux/Unix gibt es auch noch, sollte jedoch zugunsten von iconv nicht verwendet werden. iconv ist der Nachfolger, ist umfangreicher, und zu recode las ich irgendwann mal eine Warnung.)
Lo!
Hi,
Was hat er dann davon? Sabotieren kann immer jemand. Wenn jemand Mist machen will, hat er noch ganz andere Möglichkeiten als eine andere Zeichenkodierung zu verwenden.
Haste auch wieder recht.
Passt denn der Inhalt zur Angabe? Zeigt phpMyAdmin alles (die Umlaute vor allem) richtig an?
Jau. Wird alles pikobello angezeigt.
Ich hatte nur zuletzt 2 Einträge, in denen diese typischen Umlautfehlerzeichen drin waren und bei denen ich keine Ahnung habe, woher sie kommen. Ich mutmaße auf falsch eingestellte Browserbeim User (bzw. falsches Zeichenkodierungsraten beim Browser).
- Datenbankinhalt umkodieren, also jedes einzelne String-Feld. Wenn es nicht zu viele sind, mach es zu Fuß, ansonsten lass dir ALTER-TABLE-Statements erstellen.
Na, es sind schon zu viele. Könnte ich nicht auch einen Dump erzeugen und per Texteditor alle Kodierungen suchen und ersetzen?
Zusätzlich kannst du noch die Angabe der Tabelle und die der Datenbank umstellen.
Wo genau macht man das bei phpmyadmin?
Bis hier hin kannst du alles mit dem phpMyAdmin machen oder kontrollieren. Den Teilweg zwischen DBMS und PHP kannst du schlecht prüfen, weil du zwecks Ausgabe üblicherweise den Teilweg zwischen PHP/Webserver und dem Browser benötigst.
Jau, stimmt.
- Also, nach jedem mysql_connect (oder wenn du mysqli verwendest dessen Äquivalent) rufst du mysql_set_charset('utf8') auf
Ui, davon habe ich einige.
Der legt nur die Default-Werte fest. Alles andere kannst du problemlos überschreiben. Im Falle der Verbindungskodierung ...
Welche relevanten für mein Problem gibt es denn noch?
- PHP-Code-Dateien müssen nicht zwangsläufig bearbeitet werden. Wenn du nur Code drin stehen hast,
Nein, ich habe nicht nach Code und Templates getrennt, sondern alle Ausgaben im Code mit drin.
- PHP-Code. Wenn du die Daten nur vom DBMS zum Browser und wieder zurück durchreichst, ohne Stringverarbeitung anzuwenden, dann brauchst du nichts weiter zu machen.
Im Wesentliche nutze ich
mysql_real_escape_string
htmlspecialchars
trim
nl2br
rawurlencode
- was sonst noch?
Welche Komponenten sind an deinem Projekt noch beteiligt? Textdateien? Dateinamen? Andere Server? Mailversand?
Ich includiere ein paar Textdateien, aus denen ich mir Konfigurationseinstellungen hole. Was ist mit denen?
Dann natürlich CSS-Daten und ich versende über die php-funktion 'mail' Emails, sowie über die Klasse 'phpmailer'.
Was meinst Du mit Dateinamen? Die sind alle a-z/0-9.
Die reine Konvertierung von Dateien geht beispielsweise mit iconv. Das ist ein Unix-Programm. Eine Windows-Version ist auf alle Fälle in Cygwin enthalten.
Ah, gut zu wissen! :-)
Grüße, Basti
Hi!
Passt denn der Inhalt zur Angabe? Zeigt phpMyAdmin alles (die Umlaute vor allem) richtig an?
Ich hatte nur zuletzt 2 Einträge, in denen diese typischen Umlautfehlerzeichen drin waren und bei denen ich keine Ahnung habe, woher sie kommen. Ich mutmaße auf falsch eingestellte Browserbeim User (bzw. falsches Zeichenkodierungsraten beim Browser).
Oder kein mysql_set_charset() respektive SET NAMES verwendet.
- Datenbankinhalt umkodieren, also jedes einzelne String-Feld. Wenn es nicht zu viele sind, mach es zu Fuß, ansonsten lass dir ALTER-TABLE-Statements erstellen.
Na, es sind schon zu viele. Könnte ich nicht auch einen Dump erzeugen und per Texteditor alle Kodierungen suchen und ersetzen?
Geht auch. Achte beim Export darauf, dass als Kodierung UTF-8 eingestellt ist, falls der PMA dich das wählen lässt. Wenn er da keine Auswahl hat (ist iconv nicht installiert und) das Ergebnis ist UTF-8-kodiert. Du kannst dann die Kollations- und charset-Angaben ändern und den Dump wieder importieren, wobei dort auf alle Fälle eine Kodierungsangabe gewählt werden kann und sollte - wieder UTF-8.
Zusätzlich kannst du noch die Angabe der Tabelle und die der Datenbank umstellen.
Wo genau macht man das bei phpmyadmin?
In der Lasche Operations/Operationen. Die gibts für jede Tabelle und für die Datenbank.
- Also, nach jedem mysql_connect (oder wenn du mysqli verwendest dessen Äquivalent) rufst du mysql_set_charset('utf8') auf
Ui, davon habe ich einige.
Keins vergessen!
Der legt nur die Default-Werte fest. Alles andere kannst du problemlos überschreiben. Im Falle der Verbindungskodierung ...
Welche relevanten für mein Problem gibt es denn noch?
Keine weiter. Wichtig sind die Feldkodierungen und die der Verbindung. Der Rest hat keine direkten Auswirkungen. (Ausnahme bei SET CHARACTER SET, aber das nimmt man ja zugunsten von mysql_set_charset() oder SET NAMES nicht. Was es damit auf sich hat, steht auf der bereits verlinkten Wiki-Seite.)
- PHP-Code-Dateien müssen nicht zwangsläufig bearbeitet werden. Wenn du nur Code drin stehen hast,
Nein, ich habe nicht nach Code und Templates getrennt, sondern alle Ausgaben im Code mit drin.
Dann musst du die im Falle von enthaltenen Nicht-ASCII-Zeichen umkodieren.
- PHP-Code. Wenn du die Daten nur vom DBMS zum Browser und wieder zurück durchreichst, ohne Stringverarbeitung anzuwenden, dann brauchst du nichts weiter zu machen.
Im Wesentliche nutze ichmysql_real_escape_string
htmlspecialchars
trim
nl2br
rawurlencode
Die sind alle unproblematisch. Sie behandeln nur ASCII-Zeichen. rawurlencode() kodiert byteweise und das passt für UTF-8.
- was sonst noch?
Welche Komponenten sind an deinem Projekt noch beteiligt? Textdateien? Dateinamen? Andere Server? Mailversand?
Ich includiere ein paar Textdateien, aus denen ich mir Konfigurationseinstellungen hole. Was ist mit denen?
Wenn da Nicht-ASCII-Zeichen drin sind, dann möchtest du die ebenfalls UTF-8-kodiert ausgeben klassen. Also umkodieren.
Dann natürlich CSS-Daten und ich versende über die php-funktion 'mail' Emails, sowie über die Klasse 'phpmailer'.
CSS kann Inhalte enthalten, meist jedoch nur ASCII-Zeug. Kodierungsangaben siehe Themen:Zeichencodierung/Webdokumente.
Auch EMails kennen den Content-Type-Header. Nimm text/plain als Typ für Textmails zuzüglich charset-Parameter. Ansonsten (für HTML) musst du ja sowieso schon den Content-Type angeben, der ebenfalls einen charset-Parameter benötigt.
Was meinst Du mit Dateinamen? Die sind alle a-z/0-9.
Dann sind die problemlos. In Richtung Dateisystem lässt sich nämlich keine Zeichenkodierung aushandeln. Da muss man probieren, welche es will, oder auf Umlaute etc. verzichten.
Lo!