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