1355 Stimmen

UTF-8 durchgängig

Ich bin dabei, einen neuen Server einzurichten und möchte UTF-8 in meiner Webanwendung vollständig unterstützen. Ich habe dies in der Vergangenheit auf bestehenden Servern ausprobiert und muss am Ende immer auf ISO-8859-1 zurückgreifen.

Wo genau muss ich die Kodierung/Chartersets einstellen? Ich bin mir bewusst, dass ich Apache, MySQL und PHP konfigurieren muss, um dies zu tun - gibt es eine Standard-Checkliste, die ich befolgen kann, oder vielleicht eine Fehlerdiagnose, wo die Unstimmigkeiten auftreten?

Dies ist für einen neuen Linux-Server, auf dem MySQL 5, PHP 5 und Apache 2 laufen.

22 Stimmen

Hier ist eine Einführung in Kodierungen im Allgemeinen und Kodierungen in PHP im Besonderen: Was jeder Programmierer unbedingt über Kodierungen und Zeichensätze für die Arbeit mit Text wissen muss

0 Stimmen

Einige aktuelle Diskussionen über PHP 7 deuten darauf hin, dass es keine Änderungen an der "offiziell aufgegebenen" Position von 2010 gibt... Es gibt etwas mehr über "PHP7 und UTF-8"?

0 Stimmen

Dieses Problem ist weit verbreitet. Aber es gibt keine schnelle Lösung, Sie müssen Folgendes einrichten utf-8 für jeden von ihnen einzeln - MySQL 5, PHP 5 ODER Apache 2.

1145voto

chazomaticus Punkte 15126

Datenspeicherung :

  • Geben Sie die utf8mb4 Zeichensatz für alle Tabellen und Textspalten in Ihrer Datenbank. Dies bewirkt, dass MySQL physisch Werte speichert und abruft, die nativ in UTF-8 kodiert sind. Beachten Sie, dass MySQL implizit den utf8mb4 Kodierung, wenn eine utf8mb4_* Kollation angegeben ist (ohne expliziten Zeichensatz).

  • In älteren Versionen von MySQL (< 5.5.3) sind Sie leider gezwungen, einfach utf8 die nur eine Teilmenge der Unicode-Zeichen unterstützt. Ich wünschte, ich würde scherzen.

Datenzugang :

  • In Ihrem Anwendungscode (z. B. PHP) müssen Sie in der von Ihnen verwendeten DB-Zugriffsmethode den Verbindungszeichensatz auf utf8mb4 . Auf diese Weise nimmt MySQL keine Konvertierung von seinem nativen UTF-8 vor, wenn es Daten an Ihre Anwendung weitergibt und umgekehrt.

  • Einige Treiber bieten einen eigenen Mechanismus zur Konfiguration des Verbindungszeichensatzes an, der sowohl seinen eigenen internen Zustand aktualisiert als auch MySQL über die Kodierung informiert, die für die Verbindung verwendet werden soll - das ist normalerweise der bevorzugte Ansatz. In PHP:

    • Wenn Sie die PDO Abstraktionsschicht mit PHP 5.3.6, können Sie charset en el DSN :

       $dbh = new PDO('mysql:charset=utf8mb4');
    • Wenn Sie Folgendes verwenden mysqli können Sie anrufen set_charset() :

        $mysqli->set_charset('utf8mb4');       // object oriented style
        mysqli_set_charset($link, 'utf8mb4');  // procedural style
    • Wenn Sie sich mit einfachen mysql aber zufällig PHP 5.2.3 verwenden, können Sie mysql_set_charset .

  • Wenn der Treiber keinen eigenen Mechanismus zum Setzen des Verbindungszeichensatzes bereitstellt, müssen Sie eventuell eine Anfrage stellen, um MySQL mitzuteilen, wie Ihre Anwendung erwartet, dass die Daten auf der Verbindung kodiert werden: SET NAMES 'utf8mb4' .

  • Die gleiche Überlegung gilt für utf8mb4 / utf8 gilt wie oben.

Ausgabe :

  • UTF-8 sollte im HTTP-Header gesetzt werden, z. B. Content-Type: text/html; charset=utf-8 . Sie können dies entweder durch die Einstellung default_charset in php.ini (bevorzugt), oder manuell mit header() Funktion.
  • Wenn Ihre Anwendung Text an andere Systeme überträgt, müssen diese ebenfalls über die Zeichenkodierung informiert werden. Bei Webanwendungen muss der Browser über die Kodierung informiert werden, in der die Daten gesendet werden (durch HTTP-Antwort-Header oder HTML-Metadaten ).
  • Bei der Kodierung der Ausgabe mit json_encode() , hinzufügen JSON_UNESCAPED_UNICODE als zweiten Parameter.

Eingabe :

  • Die Browser übermitteln die Daten in dem für das Dokument angegebenen Zeichensatz, so dass bei der Eingabe nichts Besonderes getan werden muss.
  • Falls Sie Zweifel an der Kodierung der Anfrage haben (falls sie manipuliert werden könnte), können Sie jede empfangene Zeichenkette als gültige UTF-8 Zeichenkette überprüfen, bevor Sie versuchen, sie zu speichern oder irgendwo zu verwenden. PHPs mb_check_encoding() wirkt, aber man muss es regelmäßig anwenden. Es gibt wirklich keine Möglichkeit, dies zu umgehen, da böswillige Clients Daten in jeder beliebigen Kodierung übermitteln können, und ich habe keinen Trick gefunden, um PHP dazu zu bringen, dies zuverlässig für Sie zu tun.

Andere Überlegungen zum Code :

  • Natürlich sollten alle Dateien, die Sie bereitstellen (PHP, HTML, JavaScript usw.), in gültigem UTF-8 kodiert sein.

  • Sie müssen sicherstellen, dass Sie jedes Mal, wenn Sie eine UTF-8-Zeichenkette verarbeiten, dies sicher tun. Das ist leider der schwierige Teil. Sie werden wahrscheinlich ausgiebig Gebrauch von PHPs mbstring Erweiterung.

  • PHPs eingebaute String-Operationen sind no standardmäßig UTF-8 sicher. Es gibt einige Dinge, die Sie sicher mit normalen PHP-String-Operationen machen können (wie Verkettung), aber für die meisten Dinge sollten Sie das Äquivalent mbstring Funktion.

  • Um zu wissen, was Sie tun (sprich: um es nicht zu vermasseln), müssen Sie UTF-8 kennen und wissen, wie es auf der untersten Ebene funktioniert. Schauen Sie sich einen der Links von utf8.de finden Sie einige gute Quellen, um alles zu erfahren, was Sie wissen müssen.

53 Stimmen

Ich liege nicht falsch: COLLATE impliziert CHARACTER SET. Siehe z.B. dev.mysql.com/doc/refman/5.0/de/charset-database.html .

130 Stimmen

Beachten Sie, dass MySQL nicht dieselbe Sprache spricht wie alle anderen. Wenn MySQL "utf8" sagt, bedeutet das in Wirklichkeit "irgendeine seltsam zurückgebliebene Variante von UTF-8, die aus weiß Gott welchem lächerlichen Grund auf drei Bytes beschränkt ist". Wenn Sie wirklich UTF-8 wollen, sollten Sie MySQL sagen, dass Sie dieses seltsame Ding wollen, das MySQL gerne utf8mb4 . Sparen Sie nicht an den "WTF!"s.

0 Stimmen

@chazomaticus denkst du, ich sollte mbstring auch für English.... verwenden oder reicht strlen aus? Was ist mit Griechisch?

169voto

mercator Punkte 27618

Ich möchte noch eines hinzufügen chazomaticus' ausgezeichnete Antwort :

Vergessen Sie auch nicht den META-Tag (wie diesen, oder die HTML4- oder XHTML-Version des Dokuments ):

<meta charset="utf-8">

Das scheint trivial zu sein, aber der IE7 hat mir damit schon einmal Probleme bereitet.

Ich hatte alles richtig gemacht; die Datenbank, die Datenbankverbindung und der HTTP-Header Content-Type waren alle auf UTF-8 eingestellt, und in allen anderen Browsern funktionierte es einwandfrei, aber der Internet Explorer bestand immer noch darauf, die "westeuropäische" Kodierung zu verwenden.

Es stellte sich heraus, dass auf der Seite das META-Tag fehlte. Durch Hinzufügen dieses Tags wurde das Problem gelöst.

Bearbeiten:

Das W3C hat eine ziemlich große Abschnitt für I18N . Dort gibt es eine Reihe von Artikeln zu diesem Thema, die die HTTP-, (X)HTML- und CSS-Seite der Dinge beschreiben:

Sie empfehlen, sowohl den HTTP-Header als auch den HTML-Meta-Tag (oder die XML-Deklaration im Falle von XHTML als XML) zu verwenden.

74voto

chroder Punkte 4273

Neben der Einstellung default_charset in der php.ini, können Sie den richtigen Zeichensatz mit header() aus Ihrem Code heraus, vor jeder Ausgabe:

header('Content-Type: text/html; charset=utf-8');

Die Arbeit mit Unicode in PHP ist einfach, solange Sie wissen, dass die meisten der String-Funktionen funktionieren nicht mit Unicode, und einige können Strings völlig verstümmeln . PHP betrachtet "Zeichen" als 1 Byte lang. Manchmal ist das in Ordnung (zum Beispiel, explodieren() sucht nur nach einer Bytefolge und verwendet sie als Trennzeichen - es ist also egal, nach welchen Zeichen Sie tatsächlich suchen). Aber manchmal, wenn die Funktion tatsächlich für die Arbeit mit Zeichen PHP hat keine Ahnung, dass Ihr Text Multi-Byte-Zeichen enthält, die in Unicode vorkommen.

Eine gute Bibliothek, die Sie sich ansehen sollten, ist phputf8 . Damit werden alle "schlechten" Funktionen umgeschrieben, so dass Sie sicher mit UTF8-Strings arbeiten können. Es gibt Erweiterungen wie die mb_string Ich bevorzuge jedoch die Bibliothek, weil sie portabler ist (aber ich schreibe Produkte für den Massenmarkt, daher ist das für mich wichtig). Aber phputf8 kann sowieso mb_string hinter den Kulissen verwenden, um die Leistung zu erhöhen.

43voto

Jim Punkte 18298

Warnung: Diese Antwort gilt für PHP 5.3.5 und niedriger. Verwenden Sie sie nicht für PHP Version 5.3.6 (veröffentlicht im März 2011) oder später.

Vergleiche mit Die Antwort von Palec auf PDO + MySQL und fehlerhafte UTF-8-Kodierung .


Ich habe ein Problem mit jemandem gefunden, der PDO und die Antwort war, dies für die PDO-Verbindungszeichenfolge zu verwenden:

$pdo = new PDO(
    'mysql:host=mysql.example.com;dbname=example_db',
    "username",
    "password",
    array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));

1 Stimmen

Wenn man etwas weiter sucht, ist dies nur für PHP-Versionen vor 5.3.6 notwendig. Siehe auch: http://stackoverflow.com/a/4361485/2286722 (obwohl sie eine separate $dbh->exec("set names utf8"); Ich bevorzuge die hier vorgestellte Methode). Übrigens gibt es auch einen ähnlichen Hinweis dazu als Kommentar im PHP-Handbuch: php.net/handbuch/de/pdo.construct.php#96325 .

0 Stimmen

30voto

JDelage Punkte 12296

In meinem Fall habe ich mb_split , die reguläre Ausdrücke verwendet. Daher musste ich auch manuell sicherstellen, dass die Kodierung des regulären Ausdrucks UTF-8 war, indem ich mb_regex_encoding('UTF-8');

Nebenbei bemerkt, habe ich auch entdeckt, dass ich durch die Ausführung von mb_internal_encoding() dass die interne Kodierung nicht UTF-8 war, und ich habe das geändert, indem ich mb_internal_encoding("UTF-8"); .

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X