Search code examples
zend-frameworkzend-framework2zend-db

Convert Zend\Db\ResultSet\HydratingResultSet to Array of Objects


In my Mapper class I'm extending AbstractDbMapper from ZfcBase to fetch rows from the database. A simple example would be code like this:

class MyMapper extends AbstractDbMapper
{

    //...

    public function fetchAll() {
        $select = $this->getSelect();
        return $this->select($select); // returns HydratingResultSet
    }
}

The problem is that $this->select() returns a Zend\Db\ResultSet\HydratingResultSet (containing the needed and hydrated objects). But I would like to return an array of these objects instead of a HydratingResultSet containing the objects.

The first thing to look at would be HydratingResultSet::toArray() but this returns a multidimensional array instead of an array of objects.

So I chose to do it by hand:

public function fetchAll() {
        $select = $this->getSelect();

        $results = array();
        foreach ($this->select($select) as $object) {
            $results[] = $object;
        }
        return $results; // returns array of needed objects
}

This works but looks ugly in every fetch method. Do I have to modify the code from select() to get the wanted behavior or is there an easier way?

Btw: Is it even recommended to return an array or convert it like this? Thanks for your help!


Solution

  • Update:

    There is a cleaner possibility to do it (by limos from https://stackoverflow.com/a/19266650/1275778). Adapted to my example from above it works like this:

    public function fetchAll() {
        $select = $this->getSelect();
        $results = $this->select($select);
        return \Zend\Stdlib\ArrayUtils::iteratorToArray($results); // returns desired array of objects
    }
    

    If limos posts his answer here, I will happily accept it.

    Old answer:

    Since no one could answer my question I tried to implement the cleanest option (to me): extending AbstractDbMapper to add the mentioned functionality. I document it here for anyone looking for a solution:

    MyAbstractDbMapper extends AbstractDbMapper
    {
        /**
         * @param Select $select
         * @param object|null $entityPrototype
         * @param HydratorInterface|null $hydrator
         * @return array
         */
        protected function select(Select $select, $entityPrototype = null, 
            HydratorInterface $hydrator = null)
        {
            $resultSet = parent::select($select, $entityPrototype, $hydrator);
            $results = array(); // Array of result objects
            foreach ($resultSet as $object) {
                $results[] = $object;
            }
            return $results;
        }
    }
    

    select() in MyAbstractDbMapper now returns an array of objects instead of HydratingResultSet.

    As this is getting downvoted, could someone please explain why?