В Doctrine есть удобный тип поля для хранения сложных структур дынных (массивов, в том числе ассоциативных и вложенных) — json_array. Но у него имеется один серьезный, на мой взгляд, недостаток: при работе, например, с русским языком происходит кодирование многобайтных символов, и строка «Привет» превращается в «\u041f\u0440\u0438\u0432\u0435\u0442», что, во-первых, сильно раздувает объем хранимых данных, а во-вторых, просто неудобно при просмотре содержимого таблиц.
Происходит это потому, что Doctrine использует PHP-функцию json_encode() без опций. А в PHP, начиная с версии 5.4, появилась опция JSON_UNESCAPED_UNICODE, которая как раз и предотвращает такое нежелательное кодирование.
Мы можем переопределить один из методов класса, отвечающего в Doctrine за работу с типом json_array. Далее предполагается, что мы работаем в рамках фреймворка Symfony.
Создаем файл src/AppBundle/Doctrine/Types/JsonArrayType.php (путь и пространство имен могут быть любыми, главное — правильно прописать полное имя класса в конфигурации) со следующим содержимым:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
namespace AppBundle\Doctrine\Types; use Doctrine\DBAL\Platforms\AbstractPlatform; use Doctrine\DBAL\Types\JsonArrayType as BaseJsonArrayType; class JsonArrayType extends BaseJsonArrayType { public function convertToDatabaseValue($value, AbstractPlatform $platform) { if (null === $value) { return null; } return json_encode($value, JSON_UNESCAPED_UNICODE); } } |
Дальше нужно прописать в файле конфигурации (app/config/config.yml) в разделе doctrine переопределение класса для типа json_array:
1 2 3 4 |
doctrine: dbal: types: json_array: AppBundle\Doctrine\Types\JsonArrayType |
И на этом все, теперь кириллица будет сохраняться в базу в нормальном виде. Естественно, кодировка таблиц должна быть при этом UTF-8.
В следующий раз поговорим о том, как добавить тип tinyint в Doctrine.