Я думаю многих смущает отсутствие preExecute в стандартном контроллере Symfony2. Ниже я приведу возможное решение данного вопроса при помощи внедрения зависимости через Service Container (Оригинал подсмотрен у Szymon Szewczyk).
UPDATE 20 января 2012: статья обновлена в соответствии с современными реалиями SF 2.0.9 (фактически изменения коснулись именования тага и события)
Итак, начнем с определения службы:
YAML:
# Vendor\MyBundle\Resources\config.yml services: # ... preexecute.listener: class: Vendor\MyBundle\Listener\PreExecuteListener tags: - { name: kernel.event_listener, event: kernel.controller, method: onKernelController } |
XML:
# Vendor\MyBundle\Resources\config.xml <service id="kernel.listener.pre_execute" class="Vendor\MyBundle\Listener\PreExecuteListener"> <tag name="kernel.event_listener" event="kernel.controller" method="onKernelController" priority="0"/> </service> |
Создадим также определение нашей службы в положенном ей месте:
// Vendor\MyBundle\Listener\PreExecuteListener.php namespace Vendor\MyBundle\Listener; use Symfony\Component\EventDispatcher\Event; use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Component\HttpKernel\Event\FilterControllerEvent; class PreExecuteListener { public function onKernelController(FilterControllerEvent $event) { if (HttpKernelInterface::MASTER_REQUEST === $event->getRequestType()){ $controllers = $event->getController(); // контроллер должен существовать if (isset($controllers[0])){ $controller = $controllers[0]; // метод должен существовать if(method_exists($controller, 'preExecute')){ $controller->preExecute(); } } } } } |
Вот и все! ) Теперь в нужном контроллере объявляем метод preExecute()
и наслаждаемся нашими танцами с бубном )
А почему только для мастера вызываем?
Что обычно принято складывать в preExecute?
Насчет принято – не скажу, ибо не знаю, а вот лично за себя могу сказать что иногда удобно инициализировать ряд переменных, которые используются во многих действиях, к примеру (получить логгер, или репозиторий).
Можно ли ето зделат в конструктору контролера?
Попробуйте, я несколько недель назад (до этой статьи) пробовал, но у меня не вышло, так как в момент вызова конструктора контейнер не инициализирован (по сути получается что это чуть больше чем стандартный PHP объект в этот момент). Однако если содержимое контейнера не нужно или его таки можно заполучить, то это сработает.
Если получится – отпишите комментарий )
Не думаю, что возможно. $myController->setContainer() вызывается после конструктора. Стало быть в конструкторе тот же EntityManager (репозиторий ведь через него получаем?) мы не увидим.
Как вариант можно так:
оу, щи. Заэскейпилось. Предпросмотр не помешал бы. Что там с моей учеткой, кстати?)
а вообще я пока не уверен, что буду использовать еще какие-то поля внутри контроллеров. Просто буду напрямую из контейнера все дергать, да и все. Ну может быть сделаю хелпер-методы в стиле getEntityManager($name = ‘read’).
Регистрируйся http://hudson.su/wp-signup.php ))
Не знаешь, есть для WP плагинчик превью комментария?
Спасибо. Но оно все равно требует капчу.
Про wp – не знаю, никогда блогов не вел. Только комменты пишу.
Странно, я тебя в юзерах не вижу, ты точно зарегался? )
О, добавил тебя к блогу, отпиши помогло или нет )
да, спасибо. Теперь без капчи
А еще можно сделать попроще и поменьше кода, объявив контроллеры как службы:
Код увы не запостился. Я пока не понял смысла объявлять контроллер сервисом. Может приведете пример еще раз? Или на мыло скиньте, я в комент вставлю.
сейчас отправлю почтой, а то тут что-то неладное, можно все комменты мои удалить последующие
Надо <pre> писать. Можно добавить атрибут lang=”php” например. И желательно эскейпеный текст вставлять, добавляя атрибут escaped=”true” (у меня стоит плагин WP-Syntax)
https://github.com/carlossg00/Jobeet2Bundle/blob/master/Controller/CategoryController.php а такой метод как тут не подходит?
По-моему подход схожий – смотрите там же: https://github.com/carlossg00/Jobeet2Bundle/blob/master/Resources/config/controller.xml
Об этом Neuron выше писал. Контроллер как служба (сервис).
Можно закрыть нужные методы контроллера и проводить инициализацию через __call.
Слушатель вполне элегантное решение на мой вкус.