Ein PHP-String ist nur eine Folge von Bytes, der keinerlei Kodierung zugeordnet ist. Zeichenfolgenwerte können aus verschiedenen Quellen stammen: dem Client (über HTTP), einer Datenbank, einer Datei oder aus Zeichenfolgenliteralen in Ihrem Quellcode. PHP liest all diese als Byte-Sequenzen und extrahiert niemals Kodierungsinformationen.
Solange alle Datenquellen und -ziele dieselbe Codierung verwenden, kann das Schlimmste sein, dass die Zeichenfolgenpositionen falsch sind (wenn Sie Mehrbyte-Codierungen verwenden), da PHP Bytes und keine Zeichen zählt.
Wenn die Codierungen jedoch nicht übereinstimmen (z. B. wenn Sie ein Zeichenfolgenliteral in eine als UTF-8 gespeicherte Quelldatei schreiben und es dann an eine Datenbank senden, die Latin-1 erwartet), führt PHP keine Konvertierung für Sie durch Kopieren Sie die Bytes glücklich über RAW.
Die vernünftigste Lösung lautet:
- Setzen Sie die interne Kodierung von PHP auf UTF-8.
- Speichern Sie alle Ihre Quelldateien als UTF-8.
- Verwenden Sie UTF-8 als Ausgabecodierung (vergessen Sie nicht, geeignete
Content-type
Header zu senden ).
- Stellen Sie die Datenbankverbindung so ein, dass UTF-8 (
SET NAMES UTF8
in MySQL) verwendet wird.
- Konfigurieren Sie alles andere nach Möglichkeit als UTF-8.
- Stellen Sie für alles, was Sie nicht kontrollieren können (z. B. Webservices von Drittanbietern) sicher, dass Sie die Codierung kennen, und konvertieren Sie so früh wie möglich zu UTF-8 und so spät wie möglich zurück zur anderen Codierung.
Warum UTF-8? Da es alle Unicode-Zeichen darstellen kann und somit alle vorhandenen 7-Bit- und 8-Bit-Codierungen ersetzt, und weil es binär kompatibel mit ASCII ist, ist also jede gültige ASCII-Zeichenfolge auch eine gültige UTF-8-Zeichenfolge (aber nicht vv .).
In Ihrem Beispiel passiert Folgendes.
Zunächst speichern Sie Ihre Quelldatei. Ihr Texteditor ist wahrscheinlich für die Verwendung von UTF-8 konfiguriert, sodass Ihr Zeichenfolgenliteral UTF-8-codiert auf der Festplatte erhält. PHP liest diese Datei und interpretiert den String als eine Reihe von Bytes. $original
Enthält jetzt eine UTF-8-codierte Zeichenfolge mit 7 Zeichen, die nur eine Bytefolge ist (obwohl sie mehr als 7 Bytes enthält, da jedes Zeichen durch zwei oder mehr Bytes dargestellt wird). Wenn Sie dann anrufen echo $original
, wird die codierte Zeichenfolge unverändert an den Client gesendet. Wenn Sie dem Client mitgeteilt haben, dass er mit UTF-8 rechnen soll, ist alles in Ordnung. Wenn Sie dies jedoch nicht tun, kann PHP den Unterschied nicht feststellen, und es kommt zu einem Müll im Browser. Versuchen Sie Folgendes als Experiment:
$original = "शक्नोम्यत्तुम्";
echo strlen($original);
strlen
Es ist codierunabhängig und setzt eine 8-Bit-Codierung mit fester Breite voraus, dh ein Byte pro Zeichen, sodass es nur Bytes und keine Zeichen zählt.