Хочу сразу сказать, что я новичок в Symfony и Doctrine и впервые столкнулся с подобной проблемой при использовании Symfony, но думаю, что мой опыт может кому-то пригодиться при решении подобных или похожих задач.
Фон:
Не так давно у меня была возможность загрузить некий проект Symfony2 на хост-сайт, но, как это бывает довольно часто, приложение отказалось работать на живом сервере, а когда я включил отладку, я увидел уведомление, подобное следующему :Twig_Error_Runtime: во время рендеринга шаблона было создано исключение.Причина этой ошибки заключается в том, что Twig по умолчанию экранирует весь вывод, включая использование функции htmlspecialchars() , который в данном случае спотыкается о некую Неверная многобайтовая последовательность .(«Предупреждение: htmlspecialchars() [function.htmlspecialchars]: неверная многобайтовая последовательность в аргументе в /.
/app/cache/prod/classes.php строка .
") в ".
" в строке .
И решив, что было бы неплохо посмотреть это самое Неверная многобайтовая последовательность , я пропустил вывод соответствующих переменных через необработанный фильтр в шаблоне, примерно так:
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
-
Игры-Одевалки На Рождество
19 Oct, 24 -
Рикерт, Генрих
19 Oct, 24 -
Загар (Химия Загара)
19 Oct, 24 -
Оптимизация Vista
19 Oct, 24 -
Apple-Car В Мультфильме Тачки
19 Oct, 24 -
Sass-Архитектура Для Вашего Проекта
19 Oct, 24 -
Сумасшедшие Ручки: «Раздатчик Корма»
19 Oct, 24