Как я могу создать собственный итератор для шаблона проектирования Active Record в PHP? - PullRequest
0 голосов
/ 05 июня 2018

Я пытаюсь реализовать пользовательский итератор для шаблона 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();
    }
}

Любой совет будет принят с благодарностью!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...