Php 使用具体的Zend_Db_Table_Abstract高效地迭代行集

Php 使用具体的Zend_Db_Table_Abstract高效地迭代行集,php,zend-framework,zend-db,Php,Zend Framework,Zend Db,我正在使用Zend_Db_Table_Abstract的具体实现: class DB_TestClass extends Zend_Db_Table_Abstract { protected $_name = "test.TestData"; } 如果要选择表中的所有行,我似乎有一个选项: $t = new DB_TestClass; $rowset = $t->fetchAll(); 这将返回Zend_Db_Table_行集的一个实例,该行集具有一个iterable接口,您可

我正在使用Zend_Db_Table_Abstract的具体实现:

class DB_TestClass extends Zend_Db_Table_Abstract {
    protected $_name = "test.TestData";
}
如果要选择表中的所有行,我似乎有一个选项:

$t = new DB_TestClass;
$rowset = $t->fetchAll();
这将返回Zend_Db_Table_行集的一个实例,该行集具有一个iterable接口,您可以循环并作为rowClass实例访问每个行条目:

foreach($rowset as $row) {
    var_dump($row);
}  
但是,行集已将数据库中的每一行加载到内存中(!)在小表上这是可以的,但在大表上(例如数千行),它会很快耗尽PHP可用的内存,脚本也会死掉

如何使用Zend_Db遍历结果集,一次从语句句柄中检索一行,即ala mysql_fetch_assoc()?这将允许在不使用过多内存的情况下高效地访问任意数量的行(数千行、数百万行)


提前感谢您的建议。

您可以指定将所有行一起提取的目的吗?因为如果您想对表中的所有行进行某种处理,那么您必须以任何方式将所有行放入内存。另一方面,如果您想进行分页之类的操作,可以始终使用zend_pagination对象,它一次只获取有限的行数。或者更好的是,您可以在fetchAll函数本身中设置要提取的偏移量和行数。

那么fetchAll()不能满足您的要求。 您需要使用Zend_Db_Select来获取所有记录,然后通过循环执行您想要的操作

        $select = new Zend_Db_Select ($this->getFrontController()->getParam('bootstrap')->getResource ('Db'));
        $statement = $select->from ('verses')->query ();
        $statement->execute ();


        while ($row = $statement->fetch ())
        {
            // try something like that
            $db_row = new Zend_Db_Table_Row (array ('table' => $table, 'data' => $row));

            $db_row->text = $db_row->text . '_';
            $db_row->save ();

        }

例如,我想在每一行上运行一个update语句,ala:“$row->column=”new value”$行->保存();'。使用偏移量和行数调用fetchAll以在集合中检索它们也是低效的(许多DB命中,或者如果每行包含1MB数据(如果存储BLOB,则可能),则不需要花费太多时间来耗尽可用RAM。)我不需要提取,一次将多行数据存储到RAM中。如果要在数据库中保存非常繁重的数据,可能是时候使用memcached之类的工具来缓存这些繁重的数据,以避免往返服务器并将其分发到多个服务器上。据我所知,Zend Framework的抽象表类只使用mysql_fetch_assoc函数,所以应该没有太大区别,是的,如果有多行要更新,那么我想您必须直接使用“update”命令,更新每一行没有多大意义。这样做意味着您将丢失行访问网关模式功能(因此在每一个$row上,您不能再执行:“$row->field=“new value”;$row->save();”),这是使用Zend_Db的好处之一。有没有一种方法可以利用你上面的建议把它带回来?哦,顺便说一下,看看Zend_Db_Table_Select。那可能更适合你。