Using Buffer for Resultset::rewind() after Resultset::next() called in Zend\Db
In Zend\Db, there is Resultset
which can be used as result of db records as instanceof PHP Iterator. For example, we have the following table structure:
CREATE TABLE test ( id serial NOT NULL PRIMARY KEY, name character varying(255) );
and we have the following data:
To build resultset, we can use the following code:
include './vendor/autoload.php'; use Zend\Db\Adapter\Adapter; use Zend\Db\TableGateway\TableGateway; use Zend\Db\ResultSet\ResultSet; $adapter = new Adapter([ 'username' => 'developer', 'password' => '123456', 'driver' => 'pdo_pgsql', 'database' => 'learn', 'host' => 'localhost', ]); $resultSetPrototype = new ResultSet( null, new ArrayObject([], ArrayObject::ARRAY_AS_PROPS) ); $tableGateway = new TableGateway( 'test', $adapter, null, $resultSetPrototype ); $select = $tableGateway->getSql()->select(); $resultSet = $tableGateway->selectWith($select);
On getting the data, we can go to specific record position by using next()
, for example: we want to get the 2nd record of selected data, we can use the following code:
$resultSet->current(); $resultSet->next(); var_dump($resultSet->current());
and we will get the following data:
class ArrayObject#16 (1) { private $storage => array(2) { 'id' => int(2) 'name' => string(6) "test 2" } }
However, when we need to back to first position, we can’t just use rewind()
as follow:
$resultSet->rewind(); var_dump($resultSet->current());
Above code will result wrong data, which is a next record data:
class ArrayObject#16 (1) { private $storage => array(2) { 'id' => int(3) 'name' => string(6) "test 3" } }
To make that work, we need to use buffer()
method early after result set created, so, the code will need to be:
$select = $tableGateway->getSql()->select(); $resultSet = $tableGateway->selectWith($select); $resultSet->buffer(); $resultSet->current(); // ensure hit 1st record first $resultSet->next(); // next position var_dump($resultSet->current()); // get 2nd record $resultSet->rewind(); // back to position 0 var_dump($resultSet->current()); // get 1st record again
That will show the correct data:
# second record by call of next() class ArrayObject#16 (1) { private $storage => array(2) { 'id' => int(2) 'name' => string(6) "test 2" } } # first record after call of rewind() class ArrayObject#16 (1) { private $storage => array(2) { 'id' => int(1) 'name' => string(6) "test 1" } }
on $records->buffer();
where does records come from? or should it be $resultSet?
and why do we prefer
$select = $tableGateway->getSql()->select();
$resultSet = $tableGateway->selectWith($select);
instead of
$resultSet = $tableGateway->select();
Thank you, that’s should be `$resultSet`, it fixed now. Getting `$select` from `getSql()` first make it possible to do other thing before return a resultset with ease, eg: sorting, for example:
thanks. I mostly do something like this.
$resultSet = $tableGateway->select(function($select) { $select->order(‘id ASC’); });
Just asked out of curiosity. As I did not use selectWith much.