Name: Unicode

Beitrag lesen

Ihr wart alle auf der falschen Fährte. Kurzlösung voarab: In deinem CGI-Beispiel schreibst du nach STDOUT. Du musst entweder STDOUT binmoden oder deine Ausgabedaten durch encode() jagen, bevor du sie printest.

Es folgen drei Sachverhalte zum Thema im Detail:

1. Wenn du dein Programmquellcode in UTF-8 speicherst, *musst* du use utf8; verwenden. (Das war einfach.) Das Pragma utf8 hat für dich keinen weiteren Nutzen, es sei denn, du frickelst an den Innereien von Perl5 selber, und in diesem Falle bist du ja schlau genug und hast meine Erklärung nicht nötig. ;)

2. Immer wenn du Daten empfängst, *musst* du sie dekodieren. Immer wenn du Daten wegschreibst, *musst* du sie kodieren. Dekodieren bedeutet die Umwandlung eines externen Formats nach Perls eigenem Format. Kodieren bedeutet die Umwandlung von Perls eigenem Format in einen externes Format. Nur weil du bisher damit weggekommen bist, es zu unterlassen (und alles hat funktioniert), heißt das nicht, dass du es auch in Zukunft tun kannst. Sorry für die Umstände.

Im Regelfalle heißt das in der Praxis:
a) Wenn du von Dateien, Sockets, Datenbanken und anderen Prozessen liest und schreibst, benutze eines der folgenden Konstrukte:

  
# implizit über IO-Layer über Pragma  
# http://perldoc.perl.org/open.html  
use open ':utf8';  
  
# implizit über IO-Layer über Dateidisziplin  
# http://perldoc.perl.org/functions/open.html, grep nach "disciplines"  
open my $fh, '<:utf8', 'filename' or die "could not open filename for reading: $!";  
open my $fh, '>:utf8', 'filename' or die "could not open filename for writing: $!";  
  
# implizit über IO-Layer über binmode()  
# http://perldoc.perl.org/functions/binmode.html  
open my $fh, '<', 'filename' or die "could not open filename for reading: $!";  
open my $fh, '>', 'filename' or die "could not open filename for writing: $!";  
binmode $fh => ':utf8';  

Wenn du von STDIN liest (nacktes <> tut das) und wenn du nach STDOUT schreibst (print ohne Filehandle tut das):

  
# implizit über IO-Layer über binmode()  
binmode STDIN => ':utf8';  
binmode STDOUT => ':utf8';  

  
# explizit über Encode  
# http://perldoc.perl.org/Encode.html  
# http://perlmonks.org/?node_id=551676  
use Encode qw(decode encode);  
my $input = decode('UTF-8', $q->param('par'));  
print encode('UTF-8', $html);  

3. Du kannst HTML-Formulare nicht zwingen, ein bestimmtes Format zu liefern.

http://search.cpan.org/~dankogai/Encode-2.18/lib/Encode/Supported.pod
"it is beyond the power of words to describe the way HTML browsers encode non-ASCII form data"

http://www.cl.cam.ac.uk/~mgk25/unicode.html#web
"both standardization and implementation are still a huge mess here"

Dieses Posting wurde ohne Zuhilfenahme von perl verfasst. Alle Codebeispiele sind ungetestet.

Benne, wenn du das hier gelesen hast, bitte antworte kurz.