是否可以使用Doctrine2批处理与Twig的标签无缝连接?

Jen*_*ens 2 php iterator symfony doctrine-orm twig

我有一些用例,我需要显示没有分页的数据集.为了节省内存,我宁愿使用Doctrine的批处理功能(查询迭代器).

我想知道twig是否提供任何机制(编写我自己的扩展名是正确的)以允许使用带有迭代器结果集的for标记,就像我对任何其他集合一样.

然后在我的扩展(或任何处理迭代过程)我将分离使用它们的对象.

到目前为止,我认为我唯一的选择是为标签创建自定义,因为我不认为标签的twig处理这个.

Jen*_*ens 5

考虑到:

  1. Doctrine的迭代器使用PDO的fetch方法(它一次只使用一个对象)
  2. Doctrine的迭代器实现了PHP的Iterator接口

而不是传递:

$query->getResult()
Run Code Online (Sandbox Code Playgroud)

你可以通过:

$query->iterate()
Run Code Online (Sandbox Code Playgroud)

然后在树枝而不是做:

{% for item in result %}
     {# do work with item #}
{% endfor %}
Run Code Online (Sandbox Code Playgroud)

它应该是:

{% for item in result %}
     {# doctrine's iterator yields an array for some crazy reason #}
     {% set item = item[0] %} 

     {# do work with item #}

     {# the object should be detached here to avoid staying in the cache #}
{% endfor %}
Run Code Online (Sandbox Code Playgroud)

此外,loop.last变量停止工作,所以如果你使用它,你应该找出解决问题的另一种方法.

最后,我没有编写自定义twig标签,而是创建了一个用于doctrines迭代器的装饰器来处理我需要的额外东西,唯一仍然被破坏的是loop.last var:

class DoctrineIterator implements \Iterator {

    public function __construct(\Iterator $iterator, $em) {
        $this->iterator = $iterator;
        $this->em = $em;
    }

    function rewind() {
        return $this->iterator->rewind();
    }

    function current() {
        $res = $this->iterator->current();
            //remove annoying array wrapping the object
        if(isset($res[0])) 
            return $res[0];
        else
            return null;
    }

    function key() {
        return $this->iterator->key();
    }

    function next() {
            //detach previous entity if present
        $res = $this->current();
        if(isset($res)) {
            $this->em->detach($res);
        }
        $this->iterator->next();
    }

    function valid() {
        return $this->iterator->valid();
    }
}
Run Code Online (Sandbox Code Playgroud)