zendframework/zend-db

Implementation of the Iterator interface in the Zend\Db\Adapter\Driver\Pdo\Result class

Opened this issue · 1 comments

Suppose we have a table named mytable with more than two rows in our database.
$driver is an instance of the Zend\Db\Adapter\Driver\Pdo\Pdo class.
Let's look at the following code:

$results = $driver->getConnection()->execute('SELECT * FROM mytable');
foreach ($results as $result) {
    // For some reason our loop ends up at the first level
    break;
}
// Next, in another place we do that (with the same $results object):
foreach ($results as $result) {
    echo $result['mycolumn'];    //Here we start from the second row! (though rewind() was executed)
}

The problem is with the Zend\Db\Adapter\Driver\Pdo\Result::rewind() method. Let's look at the actual implementation:

public function rewind()
{
    if ($this->statementMode == self::STATEMENT_MODE_FORWARD && $this->position > 0) {
        throw new Exception\RuntimeException(
            'This result is a forward only result set, calling rewind() after moving forward is not supported'
        );
    }
    $this->currentData = $this->resource->fetch($this->fetchMode);
    $this->currentComplete = true;
    $this->position = 0;
}

As we can see, the Exception is thrown when $this->position is greater than 0, but the Exception should be thrown when $this->position is greater than -1.
In addition to this we should correct the current() and next() methods a little bit too if we want to use them not only in foreach loops.

This repository has been closed and moved to laminas/laminas-db; a new issue has been opened at laminas/laminas-db#129.