Ich richte einen neuen Server ein und möchte UTF-8 in meiner Webanwendung vollständig unterstützen. Ich habe dies in der Vergangenheit auf vorhandenen Servern versucht und muss immer wieder auf ISO-8859-1 zurückgreifen.
Wo genau muss ich die Codierung / Zeichensätze einstellen? Ich bin mir bewusst, dass ich Apache, MySQL und PHP konfigurieren muss, um dies zu tun. Gibt es eine Standard-Checkliste, der ich folgen kann, oder kann ich möglicherweise Fehler beheben, wenn die Nichtübereinstimmungen auftreten?
Dies ist für einen neuen Linux-Server, auf dem MySQL 5, PHP, 5 und Apache 2 ausgeführt werden.
utf-8
für jede einzelne separat einrichten - MySQL 5, PHP 5 ODER Apache 2.Antworten:
Datenspeicherung :
Geben Sie den
utf8mb4
Zeichensatz für alle Tabellen und Textspalten in Ihrer Datenbank an. Dadurch kann MySQL in UTF-8 nativ codierte Werte physisch speichern und abrufen. Beachten Sie, dass MySQL implizit dieutf8mb4
Codierung verwendet , wenn eineutf8mb4_*
Sortierung angegeben wird (ohne expliziten Zeichensatz).In älteren Versionen von MySQL (<5.5.3) müssen Sie leider einfach verwenden
utf8
, was nur eine Teilmenge von Unicode-Zeichen unterstützt. Ich wünschte, ich mache Witze.Datenzugriff :
In Ihrem Anwendungscode (z. B. PHP) müssen Sie bei jeder verwendeten DB-Zugriffsmethode den Verbindungszeichensatz auf festlegen
utf8mb4
. Auf diese Weise führt MySQL keine Konvertierung von seinem nativen UTF-8 durch, wenn Daten an Ihre Anwendung übergeben werden und umgekehrt.Einige Treiber bieten einen eigenen Mechanismus zum Konfigurieren des Verbindungszeichensatzes, der sowohl seinen eigenen internen Status aktualisiert als auch MySQL über die für die Verbindung zu verwendende Codierung informiert. Dies ist normalerweise der bevorzugte Ansatz. In PHP:
Wenn Sie die PDO- Abstraktionsschicht mit PHP ≥ 5.3.6 verwenden, können Sie
charset
im DSN Folgendes angeben :Wenn Sie mysqli verwenden , können Sie anrufen
set_charset()
:Wenn Sie mit einfachem MySQL nicht weiterkommen, aber zufällig PHP ≥ 5.2.3 ausführen , können Sie anrufen
mysql_set_charset
.Wenn der Treiber keinen eigenen Mechanismus zum Festlegen des Verbindungszeichensatzes bereitstellt, müssen Sie möglicherweise eine Abfrage ausgeben, um MySQL mitzuteilen, wie Ihre Anwendung erwartet, dass Daten über die Verbindung codiert werden :
SET NAMES 'utf8mb4'
.Die gleiche Überlegung bezüglich
utf8mb4
/utf8
gilt wie oben.Ausgabe :
Wenn Ihre Anwendung Text an andere Systeme überträgt, müssen diese auch über die Zeichenkodierung informiert werden. Bei Webanwendungen muss der Browser über die Codierung informiert werden, in der Daten gesendet werden (über HTTP-Antwortheader oder HTML-Metadaten ).
In PHP können Sie die
default_charset
Option php.ini verwenden oder denContent-Type
MIME-Header manuell selbst ausgeben. Dies ist nur mehr Arbeit, hat aber den gleichen Effekt.Wenn das Ausgangssignal unter Verwendung Codieren
json_encode()
, fügtJSON_UNESCAPED_UNICODE
als zweiten Parameter.Eingabe :
Leider sollten Sie überprüfen, ob jede empfangene Zeichenfolge als UTF-8 gültig ist, bevor Sie versuchen, sie zu speichern oder irgendwo zu verwenden. PHPs machen
mb_check_encoding()
den Trick, aber Sie müssen es religiös verwenden. Daran führt kein Weg vorbei, da böswillige Clients Daten in jeder gewünschten Codierung senden können und ich keinen Trick gefunden habe, um PHP dazu zu bringen, dies zuverlässig für Sie zu tun.Nach dem Lesen der aktuellen HTML-Spezifikation sind die folgenden Unteraufzählungszeichen für modernes HTML nicht mehr erforderlich oder sogar gültig. Nach meinem Verständnis arbeiten Browser mit Daten in dem für das Dokument angegebenen Zeichensatz und senden diese. Wenn Sie jedoch auf ältere HTML-Versionen (XHTML, HTML4 usw.) abzielen, können diese Punkte dennoch nützlich sein:
accept-charset
Attribut leider allen Ihren<form>
Tags hinzu :<form ... accept-charset="UTF-8">
.<form>
Etikett.Weitere Überlegungen zum Code :
Natürlich sollten alle Dateien, die Sie bereitstellen (PHP, HTML, JavaScript usw.), in gültigem UTF-8 codiert sein.
Sie müssen sicherstellen, dass Sie dies jedes Mal sicher tun, wenn Sie eine UTF-8-Zeichenfolge verarbeiten. Dies ist leider der schwierige Teil. Sie werden wahrscheinlich die PHP-
mbstring
Erweiterung in großem Umfang nutzen wollen .PHP integrierte String - Operationen sind nicht standardmäßig UTF-8 sicher. Es gibt einige Dinge, die Sie mit normalen PHP-Zeichenfolgenoperationen sicher tun können (z. B. Verkettung), aber für die meisten Dinge sollten Sie die entsprechende
mbstring
Funktion verwenden.Um zu wissen, was Sie tun (lesen Sie: nicht durcheinander bringen), müssen Sie UTF-8 wirklich kennen und wissen, wie es auf der niedrigstmöglichen Ebene funktioniert. Unter den Links von utf8.com finden Sie einige gute Ressourcen, um alles zu erfahren, was Sie wissen müssen.
quelle
Ich möchte der hervorragenden Antwort von chazomaticus eines hinzufügen :
Vergessen Sie auch nicht das META-Tag (wie dieses oder die HTML4- oder XHTML-Version davon ):
Das scheint trivial, aber IE7 hat mir schon früher Probleme damit bereitet.
Ich habe alles richtig gemacht; Die Datenbank, die Datenbankverbindung und der HTTP-Header vom Inhaltstyp waren alle auf UTF-8 festgelegt und funktionierten in allen anderen Browsern einwandfrei. Internet Explorer bestand jedoch weiterhin auf der Verwendung der "westeuropäischen" Codierung.
Es stellte sich heraus, dass auf der Seite das META-Tag fehlte. Das Hinzufügen löste das Problem.
Bearbeiten:
Das W3C hat tatsächlich einen ziemlich großen Abschnitt, der dem I18N gewidmet ist . Sie haben eine Reihe von Artikeln zu diesem Thema - sie beschreiben die HTTP-, (X) HTML- und CSS-Seite der Dinge:
Sie empfehlen, sowohl den HTTP-Header als auch das HTML-Meta-Tag (oder die XML-Deklaration bei XHTML als XML) zu verwenden.
quelle
Zusätzlich zur Einstellung
default_charset
in php.ini können Sieheader()
vor jeder Ausgabe den richtigen Zeichensatz aus Ihrem Code senden :Die Arbeit mit Unicode in PHP ist einfach, solange Sie feststellen, dass die meisten Zeichenfolgenfunktionen nicht mit Unicode funktionieren und einige Zeichenfolgen möglicherweise vollständig entstellen . PHP betrachtet "Zeichen" als 1 Byte lang. Manchmal ist dies in Ordnung (
explode()
sucht beispielsweise nur nach einer Byte-Sequenz und verwendet sie als Trennzeichen - es spielt also keine Rolle, nach welchen tatsächlichen Zeichen Sie suchen). In anderen Fällen, in denen die Funktion tatsächlich für die Arbeit mit Zeichen ausgelegt ist , hat PHP keine Ahnung, dass Ihr Text Mehrbyte-Zeichen enthält, die mit Unicode gefunden werden.Eine gute Bibliothek zum Einchecken ist phputf8 . Dadurch werden alle "schlechten" Funktionen neu geschrieben, sodass Sie sicher an UTF8-Zeichenfolgen arbeiten können. Es gibt Erweiterungen wie die mbstring-Erweiterung, die dies auch für Sie versuchen, aber ich bevorzuge die Verwendung der Bibliothek, weil sie portabler ist (aber ich schreibe Massenmarktprodukte, das ist also wichtig für mich). Phputf8 kann jedoch mbstring hinter den Kulissen verwenden, um die Leistung zu steigern.
quelle
Ich habe ein Problem mit jemandem gefunden, der PDO verwendet, und die Antwort war, dies für die PDO-Verbindungszeichenfolge zu verwenden:
Die Seite, von der ich das genommen habe, ist nicht verfügbar, aber ich konnte es zum Glück über den Google-Cache abrufen.
quelle
$dbh->exec("set names utf8");
; ich bevorzuge die hier vorgestellte Methode). Übrigens. Es gibt auch einen ähnlichen Hinweis dazu als Kommentar im PHP-Handbuch: php.net/manual/en/pdo.construct.php#96325 .In meinem Fall habe ich
mb_split
Regex verwendet. Daher musste ich auch manuell sicherstellen, dass die Regex-Codierung utf-8 warmb_regex_encoding('UTF-8');
Als Randnotiz habe ich auch beim Ausführen festgestellt,
mb_internal_encoding()
dass die interne Codierung nicht utf-8 ist, und ich habe dies durch Ausführen geändertmb_internal_encoding("UTF-8");
.quelle
Zuallererst, wenn Sie in <5.3PHP sind, dann nein. Sie haben eine Menge Probleme zu lösen.
Ich bin überrascht, dass niemand die intl- Bibliothek erwähnt hat, die Unicode , Grapheme , String-Operationen , Lokalisierung und vieles mehr gut unterstützt (siehe unten).
Ich werde einige Informationen über die Unicode-Unterstützung in PHP von Elizabeth Smiths Folien bei PHPBenelux'14 zitieren
INTL
Gut:
Schlecht:
mb_string
ICONV
stream_filter_append($fp, 'convert.iconv.ISO-2022-JP/EUC-JP')
DATENBANKEN
Einige andere Fallstricke
Ich werde diese Antwort aktualisieren, falls sich die hinzugefügten Funktionen ändern und so weiter.
quelle
--with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd
Optionen kompilieren .Das einzige, was ich zu diesen erstaunlichen Antworten hinzufügen möchte, ist das Hervorheben des Speicherns Ihrer Dateien in der utf8-Codierung. Ich habe festgestellt, dass Browser diese Eigenschaft akzeptieren, indem sie utf8 als Ihre Codecodierung festlegen. Jeder anständige Texteditor zeigt Ihnen dies an. Beispielsweise verfügt Notepad ++ über eine Menüoption für die Dateieingabe. Sie zeigt Ihnen die aktuelle Codierung an und ermöglicht Ihnen, diese zu ändern. Für alle meine PHP-Dateien verwende ich utf8 ohne Stückliste.
Vor einiger Zeit hatte ich jemanden gebeten, utf8-Unterstützung für eine von jemand anderem entwickelte PHP / MySQL-Anwendung hinzuzufügen. Ich bemerkte, dass alle Dateien in ANSI codiert waren, also musste ich ICONV verwenden, um alle Dateien zu konvertieren, und die Datenbanktabellen ändern, um die zu verwenden utf8 charset und utf8_general_ci sortieren, fügen Sie nach der Verbindung 'SET NAMES utf8' zur Datenbankabstraktionsschicht hinzu (wenn Sie 5.3.6 oder früher verwenden, müssen Sie charset = utf8 in der Verbindungszeichenfolge verwenden) und ändern Sie die Zeichenfolgenfunktionen, um das PHP-Multibyte zu verwenden String-Funktionen äquivalent.
quelle
Ich habe kürzlich festgestellt, dass die Verwendung
strtolower()
Probleme verursachen kann, bei denen die Daten nach einem Sonderzeichen abgeschnitten werden.Die Lösung war zu verwenden
quelle
Ich habe gerade das gleiche Problem durchgearbeitet und in PHP-Handbüchern eine gute Lösung gefunden.
Ich habe meine gesamte Dateicodierung in UTF8 geändert und dann die Standardcodierung für meine Verbindung. Dies löste alle Probleme.
Quelltext anzeigen
quelle
set_charset('utf8mb4')
es nicht funktioniert, aber es hat>set_charset("utf8")
funktioniert und das wurde in den anderen Antworten nicht gezeigt.set_charset("utf8")
möglicherweise, verhält sich jedoch anders (siehe die Anmerkungen zum Unterschied zwischenutf8
undutf8mb4
und dem MySQL-Versionsverlauf). Verwendenutf8
Sie, wenn Sie müssen und nur, wenn Sie wissen, was Sie tun !In PHP müssen Sie entweder die Multibyte-Funktionen verwenden oder mbstring.func_overload aktivieren . Auf diese Weise funktionieren Dinge wie strlen, wenn Sie Zeichen haben, die mehr als ein Byte benötigen.
Sie müssen auch den Zeichensatz Ihrer Antworten identifizieren. Sie können entweder AddDefaultCharset wie oben verwenden oder PHP-Code schreiben, der den Header zurückgibt. (Oder Sie können Ihren HTML-Dokumenten ein META-Tag hinzufügen.)
quelle
Die Unicode-Unterstützung in PHP ist immer noch ein großes Durcheinander. Es ist zwar in der Lage, eine ISO8859-Zeichenfolge (die intern verwendet wird) in utf8 zu konvertieren, es fehlt jedoch die Fähigkeit, nativ mit Unicode-Zeichenfolgen zu arbeiten, was bedeutet, dass alle Zeichenfolgenverarbeitungsfunktionen Ihre Zeichenfolgen beschädigen und beschädigen. Sie müssen also entweder eine separate Bibliothek für die ordnungsgemäße Unterstützung von utf8 verwenden oder alle Funktionen zur Zeichenfolgenbehandlung selbst neu schreiben.
Der einfache Teil besteht darin, nur den Zeichensatz in HTTP-Headern und in der Datenbank usw. anzugeben. Nichts davon ist jedoch von Bedeutung, wenn Ihr PHP-Code kein gültiges UTF8 ausgibt. Das ist der schwierige Teil, und PHP gibt Ihnen dort praktisch keine Hilfe. (Ich denke, PHP6 soll das Schlimmste beheben, aber das ist noch eine Weile entfernt)
quelle
Wenn Sie möchten, dass der MySQL-Server über den Zeichensatz und nicht über PHP als Client entscheidet (altes Verhalten; meiner Meinung nach bevorzugt), fügen Sie ihn
skip-character-set-client-handshake
zu Ihremmy.cnf
, unter hinzu[mysqld]
und starten Sie ihn neumysql
.Dies kann zu Problemen führen, wenn Sie etwas anderes als UTF8 verwenden.
quelle
Die beste Antwort ist ausgezeichnet. Folgendes musste ich bei einem regulären Debian / PHP / MySQL-Setup tun:
das war alles !
quelle
Wenn Sie eine MySQL-Lösung wünschen, hatte ich nach einer Servermigration ähnliche Probleme mit zwei meiner Projekte. Nachdem ich viele Lösungen gesucht und ausprobiert hatte, stieß ich auf diese / nichts, bevor diese funktionierte):
Nach dem Hinzufügen dieser Zeile zu meiner Konfigurationsdatei funktioniert alles einwandfrei!
Ich fand diese Lösung https://www.w3schools.com/PHP/func_mysqli_set_charset.asp, als ich eine Einfügung aus einer HTML-Abfrage lösen wollte
Viel Glück!
quelle
Nur eine Notiz:
Sie sind das Problem des nicht-lateinischen Zeichen zugewandt ist , zeigt , wie
?????????
Sie eine Frage gestellt, und es wurde mit einem Hinweis auf diese kanonische Frage geschlossen haben Sie versucht , alles und egal , was man Sie noch tun bekommen??????????
ausMySQL
.Dies liegt hauptsächlich daran, dass Sie Ihre alten Daten testen , die mit dem falschen Zeichensatz in die Datenbank eingefügt und in die eigentlichen Fragezeichen konvertiert und gespeichert wurden
?
. Was bedeutet, dass Sie Ihren Originaltext für immer verloren haben und egal was Sie versuchen, Sie erhalten???????
.Wenn Sie das, was Sie aus den Antworten auf diese Frage gelernt haben, auf neue Daten anwenden, kann dies Ihr Problem lösen.
quelle
Ich hatte dieses Problem beim Anzeigen von Tabellen. Ich habe dies einfach auf jede Echoausgangsvariable gesetzt:
quelle