如何在PHP中为Active Record设计模式创建自定义迭代器?

时间:2018-06-04 21:33:12

标签: php activerecord iterator

我正在尝试为Active Records模式实现自定义迭代器,但无论我做什么,我都无法在foreach循环中正常工作。

我的目标是在处理来自数据库的大量记录时提高性能。我打算让迭代器保存一定数量的记录,并在结果集中有更多记录时自动获取下一批记录。

问题在于,即使用迭代器处理100个左右的记录,forrach循环也会产生无限循环,从而导致内存溢出。

我的数据库使用PDO,但这不应该是一个问题。

以下是自定义RecordIterator类的代码:

<?php
// If it's going to need the database, then it's 
// probably smart to require it before we start.
require_once('database.php');
class RecordIterator implements Iterator {
    private $position = 0;
    private $total = 0;
    public $resultSet;
    public $recordTable;
    public $recordClass;
    private $remainingRecords = 0;
    private $records = array(); 
    private $hasMore = true;
    public const MAX_RECORDS = 100;
    public function initialize(){
        global $database;
        $this->remainingRecords = $database->numRows($this->resultSet);
        $this->total = $this->remainingRecords;
            $this->refill();
    }
    private function refill(){
        global $database;
        $i=1;
        $this->records=array();
        while (($row = $database->fetchArray($this->resultSet)) && ($i<self::MAX_RECORDS)){
            $this->records[] = $this->recordClass::initFromRecord($row);
            $this->remainingRecords--;
            $i++;
        }
        $this->rewind();
        if($this->remainingRecords<1){
            $this->hasMore = false;
        }
    }
    public function __construct() {
        $this->rewind();
    }
    public function rewind() {
        $this->position = 0;
    }
    public function current() {
        return $this->records[$this->position];
    }
    public function key() {
        return $this->position;
    }
    public function next() {
        if($this->hasNextRecord()){
            ++$this->position;
        }elseif($this->hasMore == true){
            $this->refill();
        }else{
        }
    }
    public function hasNextRecord(){
        $nextRecord = $this->records[$this->position+1];
        $posOffset = self::MAX_RECORDS - $this->position;
        if(($posOffset>1) && !empty($nextRecord)){
            return true;
        }else{
            return false;
        }
}
    public function valid() {
        return !(empty($this->records[$this->position]));
    }
    public function __destruct(){
        $this->resultSet->closeCursor();
    }
}

非常感谢任何建议!

0 个答案:

没有答案