DDC-772: Query::iterate() returns arrays (like mixed results) #952

Closed
opened 2026-01-22 12:57:00 +01:00 by admin · 10 comments
Owner

Originally created by @doctrinebot on GitHub (Aug 27, 2010).

Jira issue originally created by user arnaud-lb:

Instead of returning queried objects, Query::iterate returns arrays with the queried objects as single elements, like mixed results :

$query = $em->createQuery('SELECT f FROM \Foo');

foreach($query->iterate() as $row) {
    print_r($row); // $row is an array(0 => \Foo instance)
}
Originally created by @doctrinebot on GitHub (Aug 27, 2010). Jira issue originally created by user arnaud-lb: Instead of returning queried objects, Query::iterate returns arrays with the queried objects as single elements, like mixed results : ``` $query = $em->createQuery('SELECT f FROM \Foo'); foreach($query->iterate() as $row) { print_r($row); // $row is an array(0 => \Foo instance) } ```
admin added the Bug label 2026-01-22 12:57:00 +01:00
admin closed this issue 2026-01-22 12:57:01 +01:00
Author
Owner

@doctrinebot commented on GitHub (Aug 27, 2010):

Comment created by @beberlei:

This is documented behaviour, not a bug

http://www.doctrine-project.org/projects/orm/2.0/docs/reference/batch-processing/batch-processing#iterating-large-results-for-data-processing

@doctrinebot commented on GitHub (Aug 27, 2010): Comment created by @beberlei: This is documented behaviour, not a bug http://www.doctrine-project.org/projects/orm/2.0/docs/reference/batch-processing/batch-processing#iterating-large-results-for-data-processing
Author
Owner

@doctrinebot commented on GitHub (Aug 27, 2010):

Issue was closed with resolution "Fixed"

@doctrinebot commented on GitHub (Aug 27, 2010): Issue was closed with resolution "Fixed"
Author
Owner

@doctrinebot commented on GitHub (Aug 27, 2010):

Comment created by arnaud-lb:

I originally checked the ::iterate() method documentation, but did not found anything about that.

Thanks!

@doctrinebot commented on GitHub (Aug 27, 2010): Comment created by arnaud-lb: I originally checked the ::iterate() method documentation, but did not found anything about that. Thanks!
Author
Owner

@amorel-ljsl commented on GitHub (Apr 25, 2016):

Hi,

This is indeed documented (here now: Iterating Large Results for Data-Processing )

But is there any valid reason for that behaviour? I mean, it's a non-sense, as there can be only one result when iterating, and everyone would expect the foreach loop to produce the objects, not an array with one object.

What am i missing?

In my case, that prevented me to use an export bundle, which expects an iterator to produce CSV, because it's not made to dig one level deep into the results it gather from the iterator...

Suggestion: add a iterateSimple() method which does what is expected.

@amorel-ljsl commented on GitHub (Apr 25, 2016): Hi, This is indeed documented (here now: [Iterating Large Results for Data-Processing](http://doctrine-orm.readthedocs.org/projects/doctrine-orm/en/latest/reference/batch-processing.html#iterating-large-results-for-data-processing) ) But is there **any valid reason** for that behaviour? I mean, it's a non-sense, as there can be only one result when iterating, and everyone would expect the foreach loop to produce the objects, not an array with one object. What am i missing? In my case, that prevented me to use an export bundle, which expects an iterator to produce CSV, because it's not made to dig one level deep into the results it gather from the iterator... Suggestion: add a `iterateSimple()` method which does what is expected.
Author
Owner

@garex commented on GitHub (Sep 30, 2016):

@amorel-ljsl workaround of this nasty behaviour is PHP7 yield.

/**
 * @return Entity[]
 */
public function findAllHuge()
{
    $iterator = $this->createQueryBuilder('e')
        ->getQuery()
        ->iterate();

    foreach ($iterator as $row) {
        yield $row[0];
    }
}
@garex commented on GitHub (Sep 30, 2016): @amorel-ljsl workaround of this nasty behaviour is [PHP7 yield](http://php.net/manual/en/language.generators.syntax.php). ``` /** * @return Entity[] */ public function findAllHuge() { $iterator = $this->createQueryBuilder('e') ->getQuery() ->iterate(); foreach ($iterator as $row) { yield $row[0]; } } ```
Author
Owner

@amorel-ljsl commented on GitHub (Sep 30, 2016):

Great tip @garex , thank you!

@amorel-ljsl commented on GitHub (Sep 30, 2016): Great tip @garex , thank you!
Author
Owner

@enumag commented on GitHub (Dec 14, 2017):

@Ocramius Can we do something about this? Like another method that would work as expected? (See this comment)

@enumag commented on GitHub (Dec 14, 2017): @Ocramius Can we do something about this? Like another method that would work as expected? (See [this comment](https://github.com/doctrine/doctrine2/issues/5287#issuecomment-214413617))
Author
Owner

@Majkl578 commented on GitHub (Dec 14, 2017):

Not in 2.x but feel free to propose/submit improvement for 3.0.

@Majkl578 commented on GitHub (Dec 14, 2017): Not in 2.x but feel free to propose/submit improvement for 3.0.
Author
Owner

@SparkDragon commented on GitHub (Apr 12, 2018):

For those who can't use PHP "yield" (wich is available from PHP 5.5), you still can create a decorator :

class IterableResultDecorator implements \Iterator
{
    protected $iterableResult;

    public function __construct(IterableResult $iterableResult)
    {
        $this->iterableResult = $iterableResult;
    }

    public function current()
    {
        $current = $this->iterableResult->current();

        return null !== $current ? $current[0] : null;
    }

    public function next()
    {
        $this->iterableResult->next();
    }

    public function key()
    {
        return $this->iterableResult->key();
    }

    public function valid()
    {
        return $this->iterableResult->valid();
    }

    public function rewind()
    {
        $this->iterableResult->rewind();
    }
}

Then you can do something like :

$results = new IterableResultDecorator($qb->getQuery()->iterate());
foreach ($results as $result) {
   // ...
}
@SparkDragon commented on GitHub (Apr 12, 2018): For those who can't use PHP "yield" (wich is available from PHP 5.5), you still can create a decorator : ```PHP class IterableResultDecorator implements \Iterator { protected $iterableResult; public function __construct(IterableResult $iterableResult) { $this->iterableResult = $iterableResult; } public function current() { $current = $this->iterableResult->current(); return null !== $current ? $current[0] : null; } public function next() { $this->iterableResult->next(); } public function key() { return $this->iterableResult->key(); } public function valid() { return $this->iterableResult->valid(); } public function rewind() { $this->iterableResult->rewind(); } } ``` Then you can do something like : ```PHP $results = new IterableResultDecorator($qb->getQuery()->iterate()); foreach ($results as $result) { // ... } ```
Author
Owner

@Ocramius commented on GitHub (Apr 12, 2018):

Please do upgrade to a newer PHP version: older releases are no longer production-ready and should be considered a business and security risk.

@Ocramius commented on GitHub (Apr 12, 2018): Please do upgrade to a newer PHP version: older releases are no longer production-ready and should be considered a business and security risk.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#952