在树枝和子控制器之间吃东西的东西

时间:2013-04-10 15:05:24

标签: symfony twig symfony-2.2

好的,首先是免责声明。我正在研究我的第一个Sf2项目并完成现有的sf1项目,将其重构为Sf2以了解所有抽屉的移动位置。

现在,发生了一些奇怪的事情,它让我撕掉了我最后的头发。

--- TL; DR:摘要---

我正在从树枝模板渲染控制器并将数组传递给该子控制器。其中一个数组值是一个对象,但该对象在到达控制器之前就消失了。

我尽可能地通过Symfony2流追逐它,并且只要我能追踪,对象就完好无损。然后我迷路了,但介于两者之间 Symfony \ Component \ HttpKernel \ Fragment \ InlineFragmentRenderer :: render()和我的(子)控制器对象消失。

这是一个功能,一个错误还是我疯了?

---详细---

我有一个twig模板,它处理一个实体对象(分配给twig变量'collection'),它包含链接的实体,如imageItem和linkedPageItem)。

我的实体已设置为扩展实现ArrayAccess的基类,因此我可以使用数组表示法访问值,无论对象是否为水合物。 (遵循此处列出的选项#1方法:http://docs.doctrine-project.org/en/latest/cookbook/implementing-arrayaccess-for-domain-objects.html)。

在树枝中,我有一条这样的线,它将一些物体传递给子控制器以渲染图像块。在渲染自己的树枝块之前,renderImage子控制器管理所有内容的清理。

以下是主枝文件中的代码:

{# blockLinks.html.twig #}
...
{{- render(controller(
    'MyBundle:Helper:renderImage',
    {
        'image': collection['imageItem'], 
        'options': {
            'html_options': { 'class': 'foo' },
            'link_options': { 'class': 'bar' },
            'link_url':     collection['item_link_url'],
            'link_page':    collection['linkedPageItem']
        }
    }
)) -}}
...

但是,renderImage子控制器永远不会收到$ options ['link_page']的值。

这很奇怪,所以我更详细地研究它。我找到了twig渲染blockLinks.html.twig的PHP文件,并深入研究了它。

我们在那里找到:

// /app/cache/dev/twig/01/30/lotsofnumbers.php
...
echo $this->env->getExtension('http_kernel')->renderFragment($this->env->getExtension('http_kernel')->controller(
    "CaponicaFdsWebsiteBundle:Helper:renderImage", 
    array(
        "image" => $this->getAttribute($_collection_, "imageItem", array(), "array"), 
        "options" => array(
            "html_options" => array("class" => "foo"), 
            "link_options" => array("class" => "bar"),
            "link_url" => $this->getAttribute($_collection_, "item_link_url", array(), "array"), 
            "link_page" => $this->getAttribute($_collection_, "linkedPageItem", array(), "array")
        )
    )
));
...

好的,看起来很好。

要弄明白我发生了什么\Doctrine\Common\Util\Debug::dump($this->getAttribute($_collection_, "linkedPageItem", array(), "array"));并报告确实这确实会返回一个Page对象。

即。它报告的内容如下:

object(stdClass)[874]
  public '__CLASS__' => string 'MyBundle\Entity\Page'
...

从缓存中编译的twig php文件开始    - > Symfony的\桥\嫩枝\延期\ HttpKernelExtension :: renderFragment()
   - > Symfony的\分量\ HttpKernel \片段\ FragmentHandler ::渲染()
   - >的Symfony \组件\ HttpKernel \片段\ InlineFragmentRenderer ::渲染()

此时对象仍然完好无损 (通过在调用$ this-> kernel-> handle($ subRequest,HttpKernelInterface :: SUB_REQUEST,false)之前转储$ subRequest-> attributes-> get('options');见第62行InlineFragmentRenderer)

我不确定接下来会发生什么。我以为它去了[\ vendor \ symfony \ symfony \ src] Symfony \ Bundle \ FrameworkBundle \ HttpKernel但我似乎无法跟踪那里的任何活动。

但是,如果我查看renderImage控制器并转储如下选项:

// MyBundle\Controller\HelperController.php

public function renderImageAction($image, $options = array()) {
    print_r(\Doctrine\Common\Util\Debug::dump($options)); // I'm sure there's a 1337 way to use the logger/toolbar for this, I'll figure that out some other day
    ...
}

我明白了:

array (size=2)
  'html_options' => 
    array (size=1)
      'class' => string 'foo' (length=3)
  'link_options' => 
    array (size=1)
      'class' => string 'bar' (length=3)

换句话说,'link_page'对象已从选项中删除 - 饥饿(并且非常可怕)的东西似乎潜伏在Symfony的深处并吃掉我的对象!

这是一个功能吗? (你不能将数组中的对象传递给子请求......也许会激怒超级严格的MVC神?)
或者这是一个错误? (吃东西不应该吃东西吗?)
或者我是否完全错过了这个特定的棒?

我希望有人可以帮助,在我失去最后一缕头发之前......

C

1 个答案:

答案 0 :(得分:0)

将渲染功能与控制器功能结合使用时,可以传递对象。我的意思是,应该支持它,并且应该按照你的方式工作。

但也许你会遇到与这个人相同的错误,它似乎与Doctrine2对象特别相关:https://github.com/symfony/symfony/issues/7124