2

ページネーションなしでデータセットを表示する必要がある特定のユースケースがあります。メモリを節約するために、Doctrineのバッチ処理機能(クエリイテレータ)を使用したいと思います。

他のコレクションと同じように、イテレータの結果セットでforタグを使用できるようにするメカニズム(独自の拡張機能を記述してもかまいません)がtwigに提供されているかどうかを知りたいです。

次に、私の拡張機能(または反復プロセスを処理するもの)で、使用されているオブジェクトを切り離します。

これまでのところ、タグの小枝がこれを処理するとは思わないので、私の唯一のオプションはタグのカスタムを作成することだと思います。

4

1 に答える 1

5

それを考慮して:

  1. DoctrineのイテレータはPDOのfetchメソッドを使用します(一度に1つのオブジェクトのみを使用します)
  2. DoctrineのイテレーターはPHPのイテレーターインターフェースを実装します

渡す代わりに:

$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変数は機能しなくなるため、これを使用する場合は、問題を解決する別の方法を見つける必要があります。

最後に、カスタムの小枝タグを作成する代わりに、必要な余分なものを処理するためのドクトリンイテレータ用のデコレータを作成しました。まだ壊れているのはloop.lastvarだけです。

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 に答える