Решение Проблемы С Кодированием Данных Из Mysql В Symfony

Хочу сразу сказать, что я новичок в Symfony и Doctrine и впервые столкнулся с подобной проблемой при использовании Symfony, но думаю, что мой опыт может кому-то пригодиться при решении подобных или похожих задач.



Фон:

Не так давно у меня была возможность загрузить некий проект Symfony2 на хост-сайт, но, как это бывает довольно часто, приложение отказалось работать на живом сервере, а когда я включил отладку, я увидел уведомление, подобное следующему :
Twig_Error_Runtime: во время рендеринга шаблона было создано исключение.

(«Предупреждение: htmlspecialchars() [function.htmlspecialchars]: неверная многобайтовая последовательность в аргументе в /.

/app/cache/prod/classes.php строка .

") в ".

" в строке .

Причина этой ошибки заключается в том, что Twig по умолчанию экранирует весь вывод, включая использование функции htmlspecialchars() , который в данном случае спотыкается о некую Неверная многобайтовая последовательность .

И решив, что было бы неплохо посмотреть это самое Неверная многобайтовая последовательность , я пропустил вывод соответствующих переменных через необработанный фильтр в шаблоне, примерно так:

 
 init connect      SET NAMES cp1251
 collation database      cp1251_general_ci
 collation      servercp1251_general_ci
 .

Оказалось, что текстовые данные кириллицей из базы почему-то приходят в кодировке cp1251, хотя кодировка импортируемой базы, таблиц и т.д. Поля, из которых брались значения, были utf8. В phpMyAdmin, который мне предоставил хостер, на вкладке «Переменные» мое внимание привлекли следующие значения параметров конфигурации сервера mysql:
  
 services:
     onconnect.listener:
         class: Dev\SomeBundle\EventListener\OnConnect
         tags:
              - { name: doctrine.event_listener, event: postConnect }


Проблема:

Очевидно, причина была именно в init Connect, который при подключении выполнял SET NAMES cp1251, поэтому все значения передавались в приложение как cp1251. НАЗВАТЬ ИМЕНА Напомню, что SET NAMES определяет кодировку, в которой клиент отправляет данные на сервер, а также кодировку, в которой сервер отправляет ответ обратно клиенту.

Проблемы такого рода обычно решаются довольно просто — сразу после подключения к базе данных в вашем приложении выполняем запрос или группу запросов типа:

{{ sometext|raw }}

Но, как по мне, любой лишний запрос к базе вообще не комильфо, как и «костыли» в коде фреймворка.

Поэтому сначала я пытался решить вопрос через техподдержку.

Ребята из техподдержки хостера сказали мне, что они не могут перенести базу данных на сервер настроенный под utf8, так как все их сервера работают с одинаковой конфигурацией на cp1251, и никто не будет менять настройки сервера из-за одного проекта, потому что Изменения коснутся всех баз данных на этом сервере (я их прекрасно понимаю).

Но проблему надо было как-то решать.



Решение:

Однако решение Symfony оказалось достаточно элегантным, что и послужило причиной написания этой статьи.

На помощь мне пришел крохотный EventListener, который я повесил на событие postConnect. Для его создания необходимо в файле app/config/config.yml (если используется YAML) в разделе «services» сделать такую запись:

SET CHARACTER SET UTF8; SET NAMES UTF8;

Теперь в нашем пакете нам нужно создать файл прослушивателя, соответствующий пространству имен, указанному в конфигурации выше ( Dev\SomeBundle\EventListener\OnConnect ).

т. е.

кладем в папку Dev/SomeBundle/EventListener файл ОнКоннект.php следующее содержание:

<Эphp //file src/Dev/SomeBundle/EventListener/OnConnect.php namespace Dev\SomeBundle\EventListener; use Doctrine\Common\Persistence\Event\LifecycleEventArgs; use Doctrine\ORM\EntityManager; class OnConnect {

Теги: #symfony #doctrine #twig #MySQL #utf8 #cp1251 #MySQL #symfony #Doctrine ORM

Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.