Хранение сериализованного объекта в базе данных MySql
у меня есть большой объект php, который я хочу сериализовать и сохранить в базе данных MySql. Кодировка таблицы -UTF-8
и столбец для хранения кодировки сериализованного объекта также UTF-8
.
проблема в том, что объект содержит текстовую строку, содержащую французские символы.
например:
Merci d'avoir passé commande avec Lovre. Voici le récapitulatif de votre commande
когда я сериализую объект, а затем снова его повторно, строка поддерживается и находится в правильном формате.
однако, когда я магазин сериализованный объект в базу данных MySql затем извлекает его снова, а затем unserialize его строка становится такой:
Merci d'avoir passé commande avec Lovre. Voici le récapitulatif de votre commande
что-то идет не так, когда я сохранить объект в базе данных.
Примечания:
- объект хранится с помощью propel ORM.
- тип столбца
text
. - строка сохраняется и считывается из html-файла.
4 ответов
строки, созданные serialize
являются двоичными строками, они не имеют определенной кодировки кодировки, а являются просто "массивом" байтов (где-как один байт-8 бит, октет).
если вы теперь возьмете такую строку и сообщите своей базе данных, что она закодирована на латинском языке-1, и ваша база данных сохранит ее в текстовом поле с кодировкой UTF-8, база данных прозрачно изменит кодировку с латинского-1 на UTF-8. UTF-8-это кодировка кодировки, которая использует более одного байта на символ для некоторых символы, например те, которые вы даете в своем вопросе, как é
.
символ é
затем сохраняется как é
внутри базы данных, которая является байтовой последовательностью UTF-8 для é
.
если вы теперь извлекаете данные из базы данных без указания, в какой кодировке они вам нужны, база данных вернет их как UTF-8.
теперь unserialize
имеет проблему, потому что двоичная строка была модифицирована таким образом, что это делает ее недействительный.
вместо этого вам нужно либо сообщить своей базе данных, что она не должна изменять кодировку при сохранении сериализованной строки, например, выбрав правильный тип столбца и кодировку (двоичное поле, BLOB-двоичный большой объектMySQL Docs см. Также БинарныеPropel Docs) - или - когда вы извлекаете данные из базы данных, вы возвращаете кодировку кодировки обратно в оригинальный формат. Первый подход (двоичное поле) лучше, потому что это именно то, что вы искали.
для данных, которые уже хранятся в базе данных в неправильном формате, необходимо исправить данные. Для этого вам сначала нужно узнать, какая перекодировка была применена, например, из какой кодировки к какой кодировке. Я предполагаю, что это латынь-1, но нет никакой гарантии. Вам нужно просмотреть кодировку ваших текущих данных и процессов приложения, чтобы найти из.
после того, как вы узнали, кодируйте значения обратно из UTF-8 в исходную кодировку.
обязательно используйте utf-8 везде - похоже, вы что-то упустили.
в вашем случае, я думаю, вы забыли установить правильную кодировку для подключения к базе данных (используя SET NAMES
заявление или mysql_set_charset ()) - но это трудно сказать, не видя ваш код (и я не знаю, продвинуть).
ниже приводится цитата из chazomaticus, который дал идеальный ответ в UTF-8 всю дорогу, перечислив все пункты, которые вы должны заботиться о:
хранение:
- указать
utf8_unicode_ci
(или эквивалент) сортировка по всем таблицам и текстовые столбцы в базе данных. Это делает MySQL физически хранить и получить значения изначально в UTF-8.извлечение:
- в PHP, в любой оболочке БД вы используйте, вам нужно установить соединение кодировку в utf8. Таким образом, MySQL делает нет преобразования из собственного UTF-8 когда он передает данные PHP. * Обратите внимание, что если вы не используете БД обертка, вам, вероятно, придется выпустить запрос, чтобы сказать MySQL, чтобы дать вам результаты в UTF-8:
SET NAMES 'utf8'
(как только вы подключитесь).доставка:
- вы должны сказать PHP, чтобы доставить правильные заголовки для клиента, поэтому текст будет интерпретироваться как UTF-8. В PHP, вы можете использовать
default_charset
РНР.параметр ini или вручную себе, что это просто больше работы, но имеет то же самое эффект.подчинение:
- вы хотите, чтобы все данные, отправленные вам браузеры должны быть в UTF-8. К сожалению, единственный способ надежно сделайте это добавьте
accept-charset
атрибут ко всем вашим<form>
теги:<form ... accept-charset="UTF-8">
.- Примечание. что спецификация W3C HTML говорит, что клиенты "должны" по умолчанию отправлять формы назад к сервер в любой charset сервер служил, но это по-видимому, только рекомендация, следовательно, необходимо быть четко каждый
<form>
тег.- хотя, на этом фронте, вы все равно хотите проверить каждую отправленную строку как действительный UTF-8, прежде чем вы попытаетесь храните его или используйте его где угодно. В PHP
mb_check_encoding()
делает трюк, но вы должны использовать его религиозно.обработка:
- это, к сожалению, трудно часть. Вы должны убедиться, что каждый раз, когда вы обрабатываете строку UTF-8, вы делаете это безопасно. Простой способ сделать это за счет широкого использования PHP
Я всегда сохраняю esrialized данные с помощьюbase64_encode()
.
Сериализованные данные иногда вызывают проблемы, но после использования base64-значения остаются только простые символы.
Я настоятельно рекомендую вам использовать json_encode вместо того, чтобы сериализовать. Однажды вы обнаружите, что пытаетесь использовать эти данные из другого места, которое не является PHP, и его хранение в JSON делает его читаемым везде; практически каждый язык поддерживает декодирование JSON и является хорошо стабильным стандартом.
ответ об использовании utf8 везде держится! :- D