Programmiersprachen

In diesem Kapitel sollen Informationen zusammengetragen werden, die beim Programmieren im Zusammenhang mit Encoding relevant sein können. Leider handelt es sich nur um eine bescheidene Auswahl, aber immerhin ist es ein Anfang.

HTML

Der folgende Hinweis zum Thema Formulardatenverarbeitung (d.h. Umgang mit dem Attribut accept-charset im Tag form) findet sich bei Selfhtml:

Um Problemen absolut aus dem Weg zu gehen und sicherzustellen, dass die gesendeten Daten in einer verarbeitungsfähigen Form bei Ihnen ankommen, beachten Sie die folgenden Hinweise:

Javascript

Wenn der Javascript-Code in die HTML-Datei eingebettet ist, hat der Sourcecode dasselbe Encoding wie die zugehörige HTML Datei.

Das Tag <script> hat auch ein Attribut namens charset, falls eine externe Javascript-Datei durch das Attribut src spezifiziert wurde.

Java

Java stellt Strings intern mit einer Unicode-Kodierung dar, das heißt: alle Operationen auf der Klasse String können bedenkenlos auf beliebige Strings angewendet werden.

Alle Ein- und Ausgabeoperationen müssen so ausgeführt werden, dass die Überführung in die interne Stringdarstellung bzw. die Umwandlung in Bytes auf der Ausgabeseite das gewünschte Encoding verwendet.

Streams sind byteorientiert, Reader/Writer sind zeichenorientiert. Das heißt: die Bytes, die man aus einem Stream liest, lassen sich nicht ohne Zusatzinformation (das verwendete Encoding) in einen String verwandeln. Daher sind auch z.B. alle Methoden der Klasse StringBufferInputStream oder auch DataInputStream.readLine() als deprecated gekennzeichnet. Ähnliches gilt etwa für die Umwandlung eines ByteArrayOutputStream in einen String.

Servlet-Programmierung: Das Interface HttpServletRequest hält Methoden bereit zum Ermitteln und Setzen der Kodierungsparameter: setCharacterEncoding und getCharacterEncoding. Auch das Interface HttpServletResponse bietet eine Methode setCharacterEncoding.

Servlet-Programmierung: Das Erzeugen von HTML-Text in einem Servlet sollte immer über einen PrintWriter erfolgen, den man mit der Methode HttpServletResponse.getWriter() erhält. Der ServletOutputStream, den man über HttpServletResponse.getOutputStream() erhält, dient ausschließlich zum Übermitteln von Binärdaten und berücksichtigt nicht die Einstellungen, die man mittels setCharacterEncoding vorgenommen hat.

Achtung: Java properties files müssen in iso-8859-1 kodiert sein. Ich gehe davon aus, dass heutzutage UTF-8 das Encoding der Wahl wäre, aber natürlich sind solche Grundsatzentscheidungen nachträglich nur schwer änderbar.

Siehe zu diesem Thema auch den Abschnitt zum Tomcat Webserver.

Perl

Wie in Java besteht auch in Perl der Knackpunkt darin, die Daten aus einer Datei erst einmal in eine korrekte interne Repräsentation zu bekommen. Die folgenden Zeilen demonstrieren, wie in Perl ab Version 5.8 das encoding-spezifische Öffnen von Ein-/Ausgabedateien aussehen kann:
open my $in, "<:encoding(utf8)", $fileName or die "Could not open input file '$fileName': $!\n";
open my $out, ">:encoding(utf8)", $fileName or die "Could not open output file '$fileName': $!\n";

Laut Perl-Dokumentation soll das Pragma utf8 verwendet werden, wenn der Sourcecode selbst Umlaute enthält, d.h. zu Beginn der Datei sollte sich in diesem Fall eine Zeile use utf8; finden. Aber Vorsicht: es zeigte sich in der Praxis, dass die Kombination mit use encoding "utf8"; dazu führt, dass Umlaute im Sourcecode innerhalb von regulären Ausdrücken eben nicht mehr korrekt behandelt werden!

Perl-Tk text widgets sind erst ab der Version 804 unicode-fähig.

Der Perl Interpreter besitzt einen switch -C um das verwendete Default-Encoding für Dateideskriptoren und Kommandozeilenparameter festzulegen:

-CA Kommandozeilenparameter (@ARGV) sind UTF-8-kodiert
-CI STDIN ist UTF-8-kodiert
-CO STDOUT ist UTF-8-kodiert
-CE STDERR ist UTF-8-kodiert
-Ci UTF-8 ist das Default-Encoding für PerlIO input streams
-Co UTF-8 ist das Default-Encoding für PerlIO output streams
-CIOEioA Kombination aus allen obigen Punkten
-CS Kurzform für -CIOE
-CD Kurzform für -Cio
-CLx Falls zusätzlich zu einem der obigen Parameter L spezifiziert wird, wird die Änderung nur wirksam, wenn eine der Umgebungsvariablen LC_ALL, LC_TYPE oder LANG mit einem entsprechenden Wert belegt ist, der auf UTF-8 schließen lässt.

Das perlrun manual bietet noch weitere detaillierte Informationen zu diesem Punkt.

Um für die Standard-Dateideskriptoren STDIN, STDERR und STDOUT ein bestimmtes Encoding festzulegen, kann man auch folgende Zeilen am Anfang des Skriptes einfügen:

PHP

Unterstützung von Multibyte Zeichen in PHP ist ziemlich rudimentär. Tatsächlich werden zur Laufzeit alle Textdaten lediglich als Bytestreams angesehen. Konsequenz daraus ist, dass Strings z.B. beim Einlesen zwar nicht explizit umgewandelt werden müssen (was schön ist), der Benutzer nach dem Import der Daten aber selbst darauf achten muss, dass er Multibyte-Operatoren darauf anwendet, wenn nötig (was sehr fehlerintensiv ist). Ein paar Anmerkungen:

Die globale PHP-Konfigurationsdatei enthält einige globale Konfigurationsoptionen, die den Umgang mit den verschiedenen Kodierungsmöglichkeiten erleichtern sollen. Da es sich um globale Parameter handelt, stellen diese Optionen natürlich auch potenzielle Fallstricke für den Benutzer dar. Beispiele für solche globale Konfigurationsoptionen sind etwa

Als Programmierer ist darauf zu achten, dass man sich nicht auf diese konfigurierbaren Eigenschaften von php verlassen sollte, bzw. dem Betreiber des Webservers entsprechende Vorgaben macht, wenn dies möglich ist.

Es gibt keine speziellen Parameter beim Öffnen oder Schließen von Dateien, die ein bestimmtes Encoding festlegen. Gelesen wird eine Bytefolge und die bleibt so erhalten, wie sie ist.

Strings in PHP werden am besten mit den Multibyte String Functions bearbeitet. Hier kann man dann auch explizit das Encoding festlegen, in dem die Daten vorliegen.

Der Defaultwert für das Encoding wird im Konfigurationsparameter mbstring.internal_encoding festgelegt.

Das Encoding von Ausgaben in HTML-Seiten kann folgerndermaßen beeinflusst werden:
mb_http_output("UTF-8");
ob_start("mb_output_handler");

Der Datenaustausch zwischen HTML-Formularen und PHP mittels POST-Variablen kann mit dem Attribut accept-charset des form Tags beeinflusst werden. Im Gegensatz zum Datenaustausch mittels GET-Variablen kann der Benutzer das Encoding in diesem Fall also explizit festetzen!

Falls der Webserver so konfiguriert ist, dass alle Seiten vom Typ 'text/html' fest mit ISO-8859-1-Encoding ausgeliefert werden, kann man dieses Problem umgehen, indem man einfach die Zeile header('Content-Type: text/html; charset=utf-8'); am Anfang(!) der Seite einfügt.