Php 控制器的全局部分行为

Php 控制器的全局部分行为,php,templates,symfony,Php,Templates,Symfony,我的应用程序中的大多数控制器都有一个基本控制器,如下所示: class BaseController extends \Symfony\Bundle\FrameworkBundle\Controller\Controller { /** * * @Route("/") */ public function indexAction($partial = false) { $this->partial = $par

我的应用程序中的大多数控制器都有一个基本控制器,如下所示:

class BaseController extends \Symfony\Bundle\FrameworkBundle\Controller\Controller
{
    /**
     * 
     * @Route("/")
     */
    public function indexAction($partial = false)
    {
            $this->partial = $partial;
        $this->currentAction = 'index';

        return $this->r();
    }
}
这伴随着一组模板,这些模板可以是带有布局的完整html页面,也可以只是内容。这是通过模板中的一行完成的:

{% extends this.partial ? "SomeProject:_base:partial.html.twig" : "SomeProject::layout.html.twig" %}
其中,这是控制器参考的一部分

然后可以在其他控制器中呈现这些模板,而无需通过复制布局

{% render 'SomeProject:SomeController:index' with  { "partial":true }  %}
我对这种方法的问题是:

每个需要成为部分控制器的操作都必须有$partial参数。由于大多数动作都有可能是局部的,因此所有控制器都必须使用它。 每个可能的局部操作都必须有$this->partial=$partial行,这很容易被忘记。
它有一个更干净的方式,使用一些符号或树枝魔术覆盖渲染标签等。为了解决上述问题?

我在大多数控制器中重写了render方法,以便将一些标准变量注入模板中。它似乎工作得很好,但它所能做的就是使从控制器渲染模板变得更容易,因为您不必显式地将$this传递给模板

我不太确定将引用传递给控制器是否是一个好主意。至少在你的例子中,只需传递partial就可以了


你真的需要给你的模板这个部分功能吗?有两个模板似乎更容易,一个用于页面,一个用于部分。但也许您的用例需要它。

经过一些研究和对内部的挖掘,我想出了一个优雅的解决方案

答案是构建一个事件监听器。更准确地说:一个控制器侦听器,其类的内容如下所示。这允许在不更改控制器代码的情况下透明地处理部分数据

class ControllerListener
{
    /**
     *
     * @param BaseController $ctrl
     * @param Request $request
     * @return BaseController 
     */
    public function injectPartial($ctrl,Request $request)
    {
        if ($ctrl instanceof BaseController)
        {
            if ($request->get("partial",false))
                $ctrl->setPartial($request->get ("partial"));
        }
        return $ctrl;
    }

    public function onKernelController(FilterControllerEvent $event)
    {
        $ctrl = $event->getController();
        $ctrl[0] = $this->injectPartial($ctrl[0], $event->getRequest());
        $event->setController($ctrl);
    }
}

覆盖渲染是为细枝文件设置标准变量的一个非常好的方法,而这正是我设置该变量的地方-我发现这在某种程度上加快了开发速度,因为我有很多方法可供使用,是的-我意识到这会导致视图中的逻辑过多。我的文件有两个模板,但是在一个有几百个视图的项目中,如果结果可以用另一种方式实现,那么制作一个事实上无用的文件真的是太过分了。