Suchen
Inside Wiki
Nützliche Links
phpforum.de Tipp
 
phpforum.de bei Facebook
 
phpforum.de bei Twitter
 

Zurück   PHP Forum: phpforum.de > phpforum.de Wiki > phpforum.de Wiki

PHP Wiki Dieses Wiki sammelt Lösungen, zu Problemen, welche immer wieder im Forum auftauchen.

 
 
Artikel-Optionen Ansicht
  #1  

Standard UTF-8

 
UTF-8
 

Tutorials - Inhalte

 

Allgemeines

 
Anmerkung: Dieser Artikel behandelt speziell den Zeichensatz UTF-8. Sämtliche Beschreibungen lassen sich jedoch auch auf alle anderen Zeichensätze übertragen.
UTF-8 (Unicode Transformation Format 8bit) ist eine weit verbreitete Zeichencodierung. Mit ihr kann man Sonderzeichen aus verschiedenen Sprachen ohne Probleme darstellen und man muss keine HTML-Entities verwenden. Maximal können mit UTF-8 1.114.112 verschiedene Zeichen dargestellt werden.
Eine ausführliche Beschreibung zu UTF-8 ist bei Wikipedia zu finden.

Wer noch nie mit Unicode Kontakt hatte, sollte hiermit beginnen: The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)

Warum UTF-8?


Mit einem gewöhnlichen Zeichensatz z.B. dem im deutschen Sprachraum normalerweise verwendeten ISO 8859-1(latin1), lassen sich nur eine sehr begrenzte Anzahl von Zeichen darstellen. Dies rührt aus der Zeit, als Speicher noch knapp und sehr kostbar war. Ein Zeichen besteht hier aus 8bit. Es gibt also 2^8 mögliche Kombinationen(Ein Bit kann zwei Zustände einnehmen; 0 und 1. Deshalb zwei hoch acht.) 2^8 ergibt 256 Zeichen. Das ist nicht sonderlich viel. 10 Zahlen, Alphabet klein, Alphabet groß, ein paar unsichtbare Steuerzeichen(z.B. neue Zeile, Zeilenvorschub), ein paar Sonderzeichen... und schon sind die 256 Zeichen weg. Da aber die z.B. Franzosen andere Zeichen wie â haben, dafür aber kein ä, benötigen sie einen anderen Zeichensatz. Dies ist nur ein Beispiel. Viel schlimmer ist es mit kyrillischen oder gar chinesischen Zeichen. Jeder benötigt einen anderen Zeichensatz.
Zeichensätze sind also eine Last aus vergangenen Zeiten. Heute ist Speicher nicht mehr knapp. Deshalb wurde UTF-8 erfunden. UTF-8 kann bis zu 4 Byte lang sein. Also 4*8=32Bit. Dies sind genug Kombinationsmöglichkeiten um sämtliche Zeichen eindeutig darstellen zu können.
Es wird empfohlen, UTF-8 zu verwenden.

Verwenden von UTF-8


Wenn man UTF-8 in seinen PHP-Scripten verwenden will, muss man auf allen Ebenen UTF-8 einstellen. Dies kann besonders bei PHP sehr vielschichtig sein:
  • Dateien (PHP-Dateien, CSS-Dateien, JS-Dateien, usw. usf.) müssen in UTF-8 gespeichert werden.
  • Daten in der Datenbank (Daten in Tabellenzellen)
  • Verbindungen zu Datenbanken (Der Weg, auf dem die Daten von PHP zur Datenbank geschickt werden)
  • Anzeige im Client (Dem Browser muss mitgeteilt werden, dass die Webseite in UTF-8 vorliegt)

Texteditor


Zuerst muss man seinen Texteditor auf UTF-8 umstellen. Dazu ist zu beachten, dass er kein Byte Order Mark (BOM) an den Anfang des Dokuments setzt. Dies führt sonst zu Problemen mit PHP.
Wenn man schon Dokumente in einem anderen Zeichensatz erstellt hat, muss man diese bei vielen Texteditoren öffnen und den Inhalt in ein neues Dokument mit dem UTF-8 Zeichensatz kopieren. Einige Editoren unterstützen auch das direkte Umwandeln. Dann ist das Kopieren nicht nötig.

Windows Editor


Um Dateien in UTF-8 zu speichern wählt man Datei->Speichern Unter. Dort kann man die Codierung einstellen.

Dreamweaver

  1. Öffnen des Menüs Bearbeiten->Voreinstellungen
  2. Wählen der Kategorie "Neues Dokument"
  3. Unter "Standardkodierung" Unicode(UTF-8) auswählen
  4. Das Häkchen bei "Unicode-Signatur (BOM) einschließen" entfernen

Notepad++


Aktuelles Dokument umwandeln

  • Menü Format -> Kodiere als UTF-8 (ohne BOM)

Neue Dokumente

  1. Menü Einstellungen -> Einstellungen
  2. Register Neues Dokument
  3. Unter Enkodierung UTF-8 ohne BOM wählen

Zend Studio for Eclipse


Aktuelles Dokument umwandeln

  1. Edit->Set Encoding

Neue Dokumente

  1. Window->Preferences
  2. "Encoding" ins Suchfeld eingeben
  3. Bei den angezeigten Optionen kann man dann für die einzelnen Dateitypen das Encoding einstellen

Cascading Style Sheets


Um in CSS Dokumenten UTF-8 zu verwenden, muss man an den Anfang der Datei
Code (Css):
@charset "utf-8";

schreiben.

(X)HTML


Um in HTML Dokumenten UTF-8 zu verwenden, schreibt man
HTML Quellcode:
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />

in den Head-Bereich des Dokuments. Diesen Schritt kann man sich sparen, wenn man entweder in der Konfiguration des Servers oder mit der header-Funktion in PHP ein Character Set angibt. Das in den HTTP-Headern angegebene Character Set hat grundsätzlich Vorrang vor einem meta-Element.

HTML5


in HTML5 ist die Charset-Angabe wie bei (X)HTML weiterhin gültig, stattdessen kann jedoch auch die folgende verkürzte Version verwendet werden:
HTML Quellcode:
<meta charset="utf-8">


XML


Für XML verwendet man am Anfang der Datei
Code:
<?xml version="1.0" encoding="utf-8" ?>

Die Angabe des Encodings darf man sich im Falle von UTF-8 aber sparen. UTF-8 ist ohnehin das Standard-Encoding für XML. Wichtiger ist, daß die Datei im UTF-8 Format gespeichert wurde und mit entsprechenden HTTP-Headern ausgeliefert wird.

Apache


Beim Apachen kann man die Verwendung von UTF-8 entweder in der httpd.conf für den ganzen Server, oder in .htaccess Dateien für einzelne Ordner festlegen. Dazu kann man drei verschiedene Direktiven verwenden:
  1. Man kann das Character Set in der AddType Direktive angeben:
    Code:
    #Für PHP-Dateien:
    AddType application/x-httpd-php;charset=utf-8 .php
    AddType application/x-httpd-php-source;charset=utf-8 .phps
    #Für Cascading Style Sheets:
    AddType text/css;charset=utf-8 .css
    #Für HTML Dokumente:
    AddType text/html;charset=utf-8 .html .htm
    #Für XHTML Dokumente:
    AddType application/xhtml+xml;charset=utf-8 .xhtml

  2. Man kann das Character Set aber auch mit AddCharset getrennt von den Content-Types festlegen:
    Code:
    AddCharset utf-8 .css .htm .html .xhtml .php

  3. Oder man gibt das Character Set mit AddDefaultCharset pauschal für sämtliche(!) Text- und HTML-Dateien auf einmal an:
    Code:
    AddDefaultCharset utf-8

PHP


Wenn man keinen Zugriff auf die httpd.conf hat und auch keine .htaccess Datein anlegen darf, kann man die entsprechenden HTTP Header auch mit PHP senden:
PHP Quellcode:
header('Content-Type: text/html; charset=utf-8');

Dies muss ganz am Anfang der Datei stehen, da HTTP-Header grundsätzlich vor jeder Ausgabe stehen müssen.

Alternativ kann man in der php.ini die Direktive default_charset verwenden.
Code:
default_charset = "utf-8"


Entwickelt man für PHP-Versionen >=5.3, so sollte in jeder Datei außerdem die Codierung des Codeblocks per declare() angegeben werden.

Mit PHP auf dem Dateisystem


Da PHP erst in der Version 6 eine vollständige Implementierung von Unicode erfahren hat, ist es unter Windos bis und mit Version 5.3 nicht möglich UTF-8 Strings als Datei oder Verzeichnisnamen zu verwenden. Strings die UTF-8 kodiert sind und für einen Dateinamen herhalten sollen, müssen unter
Windows also zwingend mit utf8_decode behandelt werden. Ansonsten entstehen falsche Dateinamen.
Hierzu kann ein Schnipsel wie der folgende verwendet werden.
PHP Quellcode:
$name = 'döner';
if (DIRECTORY_SEPARATOR=="\\") { // Windows Server
    $folderName=utf8_decode($name);
} else {
    $folderName=$name;
}
mkdir($foldername);

Bug auf bugs.php.net
Betroffen sind alle Funktionen die auf dem Dateisystem des Servers schreibenden Zugriff haben.
So auch move_uploaded_files

HTML-Formulare


Um Daten, die aus Formularen kommen, korrekt zu verarbeiten, muss im form-Tag das Attribut accept-charset notiert werden.
Code:
<!-- Beispiel -->
<form accept-charset="utf-8" method="post" action="formular.php">

MySQL


Um die Datenbankverbindung in der PHP-Anwendung auf UTF-8 zu setzen, sind folgende Varianten empfehlenswert:
PHP Quellcode:
// mysqli-Extension, prozedurale Schreibweise
mysqli_set_charset($db_link, 'utf8');

// mysqli-Extension, objektorientierte Schreibweise
$db_link->set_charset('utf8');

// PDO
$dsn = 'mysql:host=localhost;dbname=my_db;charset=utf8';
$dbh = new PDO($dsn, 'my_user', 'my_password');

// mysql-Extension (veraltet)
mysql_set_charset('utf8', $db_link);
Die Zeichenkodierung sollte beim Verbindungsaufbau, bzw. kurz danach gesetzt werden.


E-Mail Versand


Allgemein


Um E-Mails in UTF-8 zu versenden muss der Content-Type im E-Mail Header übergeben werden. Der Content-Type gilt allerdings nur für den Mail-Body, für das Subject gleich mehr.

Mail in UTF-8 versenden:
PHP Quellcode:
$mail_header = "Content-type: text/plain; charset=UTF-8;\r\n";


Das Subject ist eine Besonderheit. Bedingt durch die Tatsache, dass bei IMAP beim Abhohlen der Nachrichtenliste keine Mail-Header übertragen werden, können diese auch nicht beachtet werden.

In dem Fall muss das Subject wie folgt in UTF-8 dekodiert werden:
PHP Quellcode:
$subject= mb_encode_mimeheader($subject,"UTF-8", "B", "\n");

Es wird davon ausgegangen, dass der Subject bereits UTF-8 kodiert wurde!

Beispiel:
Code:
Subject ÖÄÜ öäü ßß & FOO

wird zu:
Code:
Subject =?UTF-8?B?w5bDhMOcIMO2w6TDvCDDn8OfICYgRk9P?=

PHPMailer


Beim PHPMailer kann man das Charset durch setzen der Eigenschaft $CharSet verändern.
PHP Quellcode:
$mailer->CharSet = 'UTF-8';


Ein bestehendes Projekt auf UTF-8 umstellen


Die Umstellung eines bestehenden Projekts ist nicht trivial. Ob es sich lohnt und überhaupt sinnvoll ist, hängt im Einzelfall davon ab, wie gut der Quelltext strukturiert ist und wie viel Zeit bereits in die Entwicklung geflossen ist. Dieser Abschnitt soll ein paar hilfreiche Tips geben, wenn man sich für eine solche Umstellung entscheidet.

(Hinweis: Es wird von einer Umgebung mit mindestens PHP 5.3 und MySQL 5.1 ausgegangen)

Schritt 1: Umwandeln der Quelltextdateien


Zunächst einmal sollten sämtliche Quelltextdateien einheitlich mit UTF-8-Codierung gespeichert werden. Um sich die vorhandene Codierung anzeigen zu lassen, kann dieses Kommando verwendet werden:
Code:
find /path/to/phpfiles -type f -exec file --mime-encoding '{}' ';'

Die Ausgabe sieht dann etwa so aus:
Code:
./db/mysql/controller.class.php: iso-8859-1
./db/mysql/datahandler.class.php: iso-8859-1
./db/mysql/defaultdatamodel.class.php: iso-8859-1
./db/mysql/sqltxtinterface.class.php: iso-8859-1
./db/mysql/table.class.php: iso-8859-1

So kann man schnell feststellen, ob sich Dateien im Projekt befinden, die bereits UTF-8 codiert sind und somit nicht nochmals konvertiert werden dürfen.

Man kann die Dateien nun von Hand mit einem Editor umstellen (wie weiter oben beschrieben), oder man behilft sich mit einem kleinen Shellskript (sicherheitshalber vorher ein Backup machen!):
Code:
find /path/to/phpfiles -name '*.php' -o -name '*.phtml'|while read DATEI; do if file -b --mime-encoding $DATEI|grep -q 'iso-8859'; then mv "$DATEI" "${DATEI}-CONVTEMP" && iconv -f CP1252 -t UTF-8 "${DATEI}-CONVTEMP" > "$DATEI" && rm "${DATEI}-CONVTEMP" && echo " OK : $DATEI"; else echo "SKIP: $DATEI"; fi; done;

(Der find-Aufruf kann mit weiteren Dateiendungen ergänzt werden. Das Skript prüft für jede Datei die vorhandene Kodierung und ändert nur Dateien mit ISO-8859.)

Schritt 2: Überarbeitung der String-Funktionen


Dieser Teil ist mit Abstand am aufwendigsten, da er nicht automatisiert werden kann. Es müssen die verwendeten PHP-Funktionen im Quelltext herausgesucht werden, die nicht richtig mit UTF-8 und Unicode umgehen können.

Locale-Funktionen


Einige Funktionen verwenden die Locale-Informationen der C-Bibliothek, dazu gehören insbesondere strftime() für die Datumsformatierung oder auch escapeshellarg(). Für Linux und OS X kann man in den meisten Fällen einfach eine passende UTF-8-Locale wählen:
PHP Quellcode:
setlocale(LC_ALL, 'de_DE.UTF-8', 'deu_deu');

Unter Windows wird die Angelegenheit schwieriger, weil dort keine Unicode-Locales unterstützt werden und stets eine zu dem gewählten Land fest vorgegebene Standard-Codepage zum Einsatz kommt, bei "deu_deu" ist dies die CP 1252. Man muß also also die Rückgabewerte von strftime() per iconv() bzw. utf8_encode() manuell nach UTF-8 konvertieren!

Reguläre Ausdrücke (PCRE)


Grundsätzlich sind in PHP 5 die pcre_*-Funktionen binary-safe und unicodefähig, dabei ist aber folgendes zu beachten:
  • In jedem Suchmuster (Pattern) das auf Unicode-Strings angewendet wird (oder selbst Unicode-Zeichen enthält) muß der Modifier u (PCRE_UTF8) angegeben sein.
  • Achtung: Einige der Escape-Sequenzen und Assertions funktionieren erst ab PHP 5.3.4 korrekt! (Siehe: https://bugs.php.net/bug.php?id=52971)

Sonstige String-Funktionen

  • Es empfiehlt sich zunächst eine Liste zu erstellen, in der alle String-Funktionen die im Projekt verwendet werden aufgeführt sind. Am besten geht man die Funktionsliste unter http://de1.php.net/manual/en/ref.strings.php einzeln durch und sucht im gesamten Quelltext nach Vorkommnissen.
  • Anschließend bewertet man für jeden einzelnen Fund, ob die jeweilige Funktion in einem binären Kontext oder einem Zeichenkettenkontext verwendet wird, und ob die korrekte Arbeitsweise der Funktion davon abhängt, einzelne Zeichen abgrenzen zu können, um sie beispielsweise zu zählen, für einen Case-Insensitive-Vergleich heranzuziehen oder die Zeichenkette an einer Bestimmten Zeichenposition zu manipulieren. Beispiele sind strpos() oder strlen(), aber auch printf() falls ein Format mit einer Längenangabe (width specifier) verwendet wird. Insbesondere letztgenannte Funktionen müssen genau untersucht und ggf. angepasst werden, z. B. indem die Funktion durch ein passendes Gegenstück aus http://de1.php.net/manual/en/book.mbstring.php ausgetauscht wird.
  • Ansonsten muß man einfach davon ausgehen, daß in PHP 5 alle String-Funktionen wenigstens binary-safe sind und sicher mit Unicode funktionieren.
  • Zum Schluß sollte der Quelltext noch auf eventuell vorhandene Meta-Angaben oder Parameter, die noch auf das alte Encoding verweisen, durchsucht werden. Insbesondere Content-Type-Meta-Header in den html-Dateien, header()-Aufrufe für Content-Type-Header und htmlentities()-Aufrufe. Eventuell kann das Encoding auch in der Apache-Konfiguration aufgeführt sein (siehe Beschreibung oben).

Schritt 3: MySQL-Datenbank


Als letztes kommt die Datenbank zum Zuge. Es genügt zunächst, nach dem Verbindungsaufbau das Encoding festzulegen; Beispiel (Achtung: SET NAMES reicht nicht!):
PHP Quellcode:

MySQL wickelt dann bereits die gesamte Kommunikation in UTF-8 ab, auch für Tabellen und Datenbanken die noch in latin1 gespeichert sind. Dadurch erhält man die Möglichkeit, das angepasste Projekt mit unveränderten Daten aus dem Echtsystem auf Herz und Nieren zu prüfen. Umlaute und Zeichen mit Akzenten werden dann bereits in Unicode-Notation verarbeitet und sollten normal erscheinen. Erst wenn bei diesem Test keine Darstellungsfehler mehr auftreten, sollten die Tabellen mittels ALTER TABLE auf eine Unicode-Collation umgestellt werden.

Links


« Vorheriges Kapitel   Tutorials
  Nächstes Kapitel »

Erstellt von Sebbl, 03.02.2008 am 16:54
Zuletzt bearbeitet von hellbringer, 10.10.2015 am 09:38
20 Kommentare , 69877 Betrachtungen

Dieser Text steht unter der GNU-Lizenz für freie Dokumentation


 

Lesezeichen

Stichworte
charset, grundlagen, i18n, tutorial, utf-8, zeichensatz

Artikel-Optionen
Ansicht

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.

Gehe zu

Alle Zeitangaben in WEZ +2. Es ist jetzt 20:38 Uhr.


Powered by vBulletin® Version 3.8.8 (Deutsch)
Copyright ©2000 - 2016, Jelsoft Enterprises Ltd.
Powered by NuWiki v1.3 RC1 Copyright ©2006-2007, NuHit, LLC