Php 是否可以将Doctrine2批处理无缝地用于Twig';标签是什么?

Php 是否可以将Doctrine2批处理无缝地用于Twig';标签是什么?,php,symfony,doctrine-orm,iterator,twig,Php,Symfony,Doctrine Orm,Iterator,Twig,我有一些用例需要在不分页的情况下显示数据集。为了节省内存,我宁愿使用条令的批处理特性(查询迭代器) 我想知道twig是否提供了任何机制(编写我自己的扩展是可以的)来允许使用迭代器结果集,就像我使用任何其他集合一样 然后在我的扩展(或任何处理迭代过程的东西)中,我将在使用对象时分离它们 到目前为止,我认为我唯一的选择是为标记创建一个自定义,因为我认为twig's for tag无法处理这个问题。考虑到: 条令迭代器使用PDO的fetch方法(一次只使用一个对象) 条令的迭代器实现了PHP的接口 而

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

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

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

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

考虑到:

  • 条令迭代器使用PDO的fetch方法(一次只使用一个对象)
  • 条令的迭代器实现了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变量停止工作,因此如果使用它,您应该找到另一种解决问题的方法

    最后,我没有编写自定义的细枝标记,而是创建了一个doctrines迭代器的Decorator来处理我需要的额外内容,唯一仍然中断的是循环。最后一个变量:

    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();
        }
    }
    

    你试过这个吗?如果您所做的只是使用iterable功能,而不是修改实体,那么我认为这应该可以正常工作,因为twig会使doctrine生成所需的内容。还应意识到,如果您在控制器中批量查询数据并将其传递给模板,或者直接在模板中传递数据,这并不重要,操作消耗的内存量几乎与整个数据集消耗的空间量完全相同。最有效的方法是通过ajax查询记录并将其附加到页面中。我希望避免同时隐藏所有对象,只隐藏当前迭代所需的对象。我不认为消耗的内存是相同的。我认为根据文档,这就是doctrine的迭代器应该发挥的作用,当然,除非我完全误解了它。(参见)此外,这甚至应该适用于json,在任何给定时刻隐藏整个集合对于生成正确的输出都是不必要的。我同意,我理解不是每个对象都会一次水合。这将使用更少的内存,但仍然会有您已经水合的每个元素的内存坐在内存中,等待页面完成渲染。1000个对象每个仅需1 5kb的区域将需要5000kb,无论是在Twig中还是在控制器中完成。但是,对100个对象进行10次请求将在每个请求中消耗1000kb。这使得服务器上的最大内存负载为1000kb,即使客户端仍然获得了完整的5000kb。