Speichern eines serialisierten Objekts in der MySql-Datenbank

8

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:

  • Das Objekt wird unter Verwendung von proprive ORM gespeichert.
  • Der Spaltentyp ist text .
  • Die Zeichenfolge wird gespeichert und von einer HTML-Datei gelesen.
Songo 02.02.2012, 08:21
quelle

4 Antworten

10

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.

    
hakre 02.02.2012, 09:10
quelle
4

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 die    Content-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.

    
oezi 02.02.2012 08:31
quelle
1

Ich speichere esialisierte Daten immer mit base64_encode() . Serialisierte Daten verursachen manchmal Probleme, aber nach dem base64-Wert bleiben nur noch einfache Zeichen übrig.

    
tim 02.02.2012 08:33
quelle
1

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

    
Ariel Scarpinelli 21.08.2015 17:55
quelle