Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Symfony2 Doctrine iterate over with while next()

I'm looking for a working solution, to iterate over a mongodb PersistentCollection in symfony2. Unfortunately this seems not to work? Symfony ignores the next() function!

while (($animal = $zooAnimals->next()) !== false) {

    $color = $animal->getColor();

    print_r($color); die; // Test and die
}

print_r('Where are the animals?'); die; // << Current result

Reference: Doctrine\ODM\MongoDB\PersistentCollection

like image 454
mate64 Avatar asked Dec 06 '22 04:12

mate64


1 Answers

This is not Symfony's "fault". This is a misunderstanding of how to iterate over an object. There are several ways to handle this for your use case. Here are some

Use a foreach!

Your PersistentCollection implements Collection which implements IteratorAggregate which implements Traversable (long way heh?).
An object which implements interface Traversable can be used in a foreach statement.

IteratorAggregate forces you to implement one method getIterator which must return an Iterator. This last also implements Traversable interface.

Usage of an iterator

Iterator interface forces your object to declare 5 methods in order to be used by a foreach

class MyCollection implements Iterator
{
    protected $parameters = array();
    protected $pointer = 0;

    public function add($parameter)
    {
        $this->parameters[] = $parameter;
    }

    /**
     * These methods are needed by Iterator
     */
    public function current()
    {
        return $this->parameters[$this->pointer];
    }

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

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

    public function rewind()
    {
        $this->pointer = 0;
    }

    public function valid()
    {
        return array_key_exists($this->pointer, $this->parameters);
    }
}

You can use any class which implements Iterator it like this - Demo file

$coll = new MyCollection;
$coll->add('foo');
$coll->add('bar');

foreach ($coll as $key => $parameter) {
    echo $key, ' => ', $parameter, PHP_EOL;
}

Use iterator with a while

In order to use this class like a foreach. Methods should be called this way - Demo file

$coll->rewind();

while ($coll->valid()) {
    echo $coll->key(), ' => ', $coll->current(), PHP_EOL;
    $coll->next();
}
like image 92
Touki Avatar answered Dec 09 '22 02:12

Touki