Symfony2 - 使用相同的控制器但基于HTTP主机的不同视图?

时间:2014-05-28 17:44:40

标签: php symfony

就像标题所说,我想使用相同的控制器,但基于HTTP主机名的不同视图。这可能吗?什么是最好的架构来完成它?

1 个答案:

答案 0 :(得分:1)

如果控制器返回null,则Symfony 2请求处理程序将调度KernelEvents :: VIEW事件。

您可以让自己成为一个视图监听器(http://symfony.com/doc/current/cookbook/service_container/event_listener.html)来捕获事件。然后,您的视图侦听器需要逻辑来根据请求参数(例如主机名)确定要创建的视图。然后视图将创建响应对象。然后,侦听器在事件中设置响应。

这是“最好的”方法吗?很难说。控制器本身没有理由无法创建视图。另一方面,使用视图侦听器,您可以与多个控制器共享视图。真的取决于你的申请。

以下是一个视图侦听器的示例,它根据_format属性启动不同的视图。

namespace Cerad\Bundle\CoreBundle\EventListener;

use Symfony\Component\DependencyInjection\ContainerAware;

use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class ViewEventListener extends ContainerAware implements EventSubscriberInterface
{

const ViewEventListenerPriority = -1900;

public static function getSubscribedEvents()
{
    return array(
        KernelEvents::VIEW => array(
            array('onView', self::ViewEventListenerPriority),
        ),
    );
}
/* =================================================================
 * Creates and renders a view
 */
public function onView(GetResponseForControllerResultEvent $event)
{
    $request = $event->getRequest();

    if ($request->attributes->has('_format')) 
    {
        $viewAttrName = '_view_' . $request->attributes->get('_format');
    }
    else $viewAttrName = '_view';

    if (!$request->attributes->has($viewAttrName)) return;

    $viewServiceId = $request->attributes->get($viewAttrName);

    $view = $this->container->get($viewServiceId);

    $response = $view->renderResponse($request);

    $event->setResponse($response);
}
# services.yml
cerad_core__view_event_listener:
    class:  '%cerad_core__view_event_listener__class%'
    calls:
        - [setContainer, ['@service_container']]
    tags:
        - { name: kernel.event_subscriber }

# routing.yml
cerad_game__project__schedule_team__show:
    path:  /project/{_project}/schedule-team.{_format}
    defaults: 
        _controller: cerad_game__project__schedule_team__show_controller:action
        _model:      cerad_game__project__schedule_team__show_model_factory
        _form:       cerad_game__project__schedule_team__show_form_factory
        _template: '@CeradGame\Project\Schedule\Team\Show\Twig\ScheduleTeamShowPage.html.twig'
        _format:     html
        _view_csv:   cerad_game__project__schedule_team__show_view_csv
        _view_xls:   cerad_game__project__schedule_team__show_view_xls
        _view_html:  cerad_game__project__schedule_team__show_view_html
    requirements:
        _format:  html|csv|xls|pdf