2

我有某些用例需要在不分页的情况下显示数据集。为了节省内存,我宁愿使用 Doctrine 的批处理功能(查询迭代器)。

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

然后在我的扩展(或处理迭代过程的任何东西)中,我会在使用对象时分离它们。

到目前为止,我认为我唯一的选择是为标签创建自定义,因为我认为 twig 的标签无法处理这个问题。

4

1 回答 1

5

考虑到:

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

而不是通过:

$query->getResult()

到树枝你可以通过:

$query->iterate()

然后在树枝中而不是这样做:

{% for item in result %}
     {# do work with item #}
{% endfor %}

它应该是:

{% 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 %}

此外,loop.last 变量停止工作,所以如果你使用它,你应该想办法解决你的问题。

最后,我没有编写自定义的 twig 标签,而是为学说迭代器创建了一个装饰器来处理我需要的额外内容,唯一仍然损坏的是 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();
    }
}
于 2012-11-10T00:29:42.853 回答