zendframework/zend-db

ResultInterface::count() is called prematurely in AbstractResultSet::initialize()

Closed this issue · 0 comments

You cannot create a result set from an unbuffered MySQLi query result. It fails during initialization. Take the example from documentation:

use Zend\Db\Adapter\Driver\ResultInterface;
use Zend\Db\ResultSet\ResultSet;

$adapter = new Zend\Db\Adapter\Adapter(array(
    'driver' => 'Mysqli',
    'database' => 'zend_db_example',
    'username' => 'developer',
    'password' => 'developer-password',
));

$stmt = $adapter->getDriver()->createStatement('SELECT * FROM users');
$stmt->prepare();
$result = $stmt->execute();

if ($result instanceof ResultInterface && $result->isQueryResult()) {
    $resultSet = new ResultSet;
    $resultSet->initialize($result);

    foreach ($resultSet as $row) {
        echo $row->my_column . PHP_EOL;
    }
}

// Fatal error:  Uncaught exception 'Zend\Db\Adapter\Exception\RuntimeException' with message 'Row count is not available in unbuffered result sets.' in vendor/zendframework/zend-db/src/Adapter/Driver/Mysqli/Result.php:316

It looks like the count property is initialized too early. It should be called only when ResultSetInterface::count() is called at the first time. In this case, the result set based on a unbuffered result still could be used as iterator.