Ich habe ein großes PHP-Objekt, das ich serialisieren und in einer MySql-Datenbank speichern möchte. Die Tabellencodierung ist UTF-8
und die Spalte für die Codierung des serialisierten Objekts ist ebenfalls UTF-8
.
Das Problem besteht darin, dass das Objekt eine Textzeichenfolge enthält, die französische Zeichen enthält.
Zum Beispiel:
%Vor%Wenn ich das Objekt serialisieren und es dann direkt wieder entserialiere, wird die Zeichenfolge beibehalten und hat das richtige Format.
Wenn ich jedoch das serialisierte Objekt in einer MySql-Datenbank ablege, es dann wieder abruft und es dann aus dem Verzeichnis nimmt, wird die Zeichenfolge wie folgt aussehen:
%Vor%Beim Speichern des Objekts in der Datenbank ist ein Problem aufgetreten.
Anmerkungen:
text
. Die von serialize
erzeugten Zeichenketten sind binäre Zeichenketten, sie haben keine spezielle Zeichenkodierung, sondern sind nur ein "Array" von Bytes (wobei ein Byte 8 Bit, ein Oktett ist).
Wenn Sie jetzt eine solche Zeichenfolge verwenden und Ihrer Datenbank mitteilen, dass sie LATIN-1-codiert ist und Ihre Datenbank sie in einem Textfeld mit UTF-8-Codierung speichert, ändert die Datenbank transparent die Codierung von LATIN-1 in UTF -8. UTF-8 ist eine Zeichensatzkodierung, die für einige Zeichen mehr als ein Byte pro Zeichen verwendet, z. B. die Zeichen, die Sie in Ihrer Frage eingeben, wie é
.
Das Zeichen é
wird dann als é
in der Datenbank gespeichert. Dies ist die Bytefolge von UTF-8 für é
.
Wenn Sie jetzt die Daten aus der Datenbank abrufen, ohne anzugeben, in welcher Kodierung Sie sie benötigen, gibt die Datenbank sie als UTF-8 zurück.
Jetzt hat unserialize
ein Problem, weil die Binärzeichenfolge so geändert wurde, dass sie ungültig wird.
Stattdessen müssen Sie entweder Ihrer Datenbank mitteilen, dass sie die Codierung nicht ändern soll, wenn sie die serialisierte Zeichenfolge speichert, z. durch Auswählen des richtigen Spaltentyps und der richtigen Codierung (binäres Feld, BLOB - Binäres großes Objekt MySQL Docs , siehe auch Binär-Typen Propel Docs ) -oder- Wenn Sie die Daten aus der Datenbank abrufen, setzen Sie die Zeichensatzkodierung wieder auf das ursprüngliche Format zurück. Der erste Ansatz (Binärfeld) ist besser, weil es genau das ist, wonach Sie suchen.
Für die Daten, die bereits in der Datenbank in einem falschen Format gespeichert wurden, müssen Sie die Daten korrigieren. Um dies zu tun, müssen Sie zuerst herausfinden, welche Neucodierung angewendet wurde, z. von welchem Zeichensatz zu welchem Zeichensatz. Ich nehme an, es ist LATIN-1, aber es gibt keine Garantie. Sie müssen die Codierung Ihrer aktuellen Anwendungsdaten und -prozesse überprüfen, um dies herauszufinden.
Nachdem Sie es herausgefunden haben, kodieren Sie die Werte zurück von UTF-8 in die ursprüngliche Kodierung.
Stellen Sie sicher, utf-8 überall zu verwenden - klingt, als hätten Sie etwas verpasst.
in Ihrem Fall, ich glaube, Sie haben vergessen, den richtigen Zeichensatz für Ihre Datenbank-Verbindung (mit einem SET NAMES
-Anweisung oder mysql_set_charset () ) - aber das ist schwer zu sagen, ohne Ihren Code zu sehen (und ich weiß nicht, treiben).
Das Folgende ist ein Zitat von chazomaticus , der eine perfekte Antwort gegeben hat in UTF-8 den ganzen Weg durch , Auflistung aller Punkte, die Sie beachten müssen:
Speicher:
- Geben Sie
utf8_unicode_ci
(oder ein gleichwertige) Sortierung auf allen Tabellen und Textspalten in Ihrer Datenbank. Dadurch wird MySQL physisch gespeichert und Werte in UTF-8 nativ abrufen.Abfrage:
- In PHP, in was auch immer DB Wrapper Sie verwenden, müssen Sie die Verbindung einrichten Zeichensatz zu utf8. Auf diese Weise tut MySQL keine Konvertierung von seinem nativen UTF-8 wenn es Daten an PHP übergibt. * Beachten Sie, dass wenn Sie keine DB verwenden Wrapper, müssen Sie wahrscheinlich ausgeben eine Abfrage, die MySQL Ihnen mitteilen soll Ergebnisse in UTF-8:
SET NAMES 'utf8'
(sobald du dich verbindest).Lieferung:
- Sie müssen PHP mitteilen, dass es zu liefern ist die richtigen Header zum Client, also Text wird als UTF-8 interpretiert. Im PHP, du kannst
default_charset
verwenden php.ini Option, oder manuell dieContent-Type
Header selbst, was ist nur mehr Arbeit, aber hat das gleiche Wirkung.Einreichung:
- Sie möchten, dass alle Daten an Sie gesendet werden Browser in UTF-8 zu sein. Leider der einzige Weg verlässlich tun dies ist die hinzufügen
accept-charset
Attribut für alle Ihre<form>
Tags:<form ... accept-charset="UTF-8">
.- Hinweis das sagt die W3C-HTML-Spezifikation Clients "sollten" standardmäßig auf Senden setzen formiert sich zurück zum Server in was auch immer charset den Server bedient, aber das ist anscheinend nur eine Empfehlung, daher die Notwendigkeit, explizit zu sein jedes einzelne
<form>
-Tag.- Obwohl, an dieser Front wirst du immer noch möchte jede übergebene Zeichenfolge überprüfen als gültig UTF-8 bevor Sie versuchen Speichern Sie es oder verwenden Sie es überall. PHPs
mb_check_encoding()
macht den Trick, aber Sie müssen es religiös verwenden.Verarbeitung:
- Das ist leider das Schwierige Teil. Sie müssen sicherstellen, dass Jedes Mal, wenn Sie eine UTF-8-Zeichenfolge verarbeiten, Du machst das sicher. Einfachste Möglichkeit das ist, indem man ausgiebig Gebrauch macht PHP
mbstring
Erweiterung.- PHPs Zeichenfolgenoperationen sind NICHT standardmäßig UTF-8 sicher. Es gibt einige Dinge, die Sie tun kann mit normaler PHP-Zeichenfolge sicher tun Operationen (wie Verkettung), aber Für die meisten Dinge solltest du das benutzen Äquivalent
mbstring
Funktion.- An Wissen Sie, was Sie tun (lesen Sie: nicht mess es), müssen Sie wirklich UTF-8 wissen und wie es am niedrigsten funktioniert mögliches Niveau. Schau dir eines der Links von utf8.com für etwas Gutes Ressourcen, um alles zu lernen, was Sie brauchen zu wissen.
- Außerdem fühle ich mich so sollte irgendwo gesagt werden, obwohl Es mag offensichtlich erscheinen: jedes PHP oder HTML Die Datei, die du bedienen wirst, sollte es sein in gültigem UTF-8 codiert.
Beachten Sie, dass Sie utf-8 nicht verwenden müssen - der wichtige Teil ist, überall den gleichen Zeichensatz zu verwenden , unabhängig davon, welcher Zeichensatz das ist. aber wenn Sie die Dinge trotzdem ändern müssen, verwenden Sie utf-8.
Ich empfehle dringend, json_encode anstelle der Serialisierung zu verwenden. Eines Tages werden Sie feststellen, dass Sie versuchen, diese Daten von einem anderen Ort zu verwenden, der kein PHP ist, und dass es in JSON gespeichert ist und überall lesbar ist. praktisch jede Sprache unterstützt die Decodierung von JSON und ist ein gut etablierter Standard.
Die Antwort über die Verwendung von utf8 überall gilt! :-D
Tags und Links php mysql encoding propel object-serialization