Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP An iterator cannot be used with foreach by reference

I have an object that implements Iterator and holds 2 arrays: "entries" and "pages". Whenever I loop through this object, I want to modify the entries array but I get the error An iterator cannot be used with foreach by reference which I see started in PHP 5.2.

My question is, how can I use the Iterator class to change the value of the looped object while using foreach on it?

My code:

//$flavors = instance of this class:
class PaginatedResultSet implements \Iterator {
    private $position = 0;

    public $entries = array();
    public $pages = array();

    //...Iterator methods...
}

//looping
//throws error here
foreach ($flavors as &$flavor) {
    $flavor = $flavor->stdClassForApi();
}

The reason for this is that sometimes $flavors will not be a an instance of my class and instead will just be a simple array. I want to be able to modify this array easily regardless of the type it is.

like image 719
shiznatix Avatar asked Apr 22 '15 13:04

shiznatix


1 Answers

I just tried creating an iterator which used:

public function &current() {
    $element = &$this->array[$this->position];
    return $element;
}

But that still did not work.

The best I can recommend is that you implement \ArrayAccess, which will allow you to do this:

foreach ($flavors as $key => $flavor) {
    $flavors[$key] = $flavor->stdClassForApi();
}

Using generators:

Updating based on Marks comment on generators, the following will allow you to iterate over the results without needing to implement \Iterator or \ArrayAccess.

class PaginatedResultSet {
    public $entries = array();

    public function &iterate()
    {
        foreach ($this->entries as &$v) {
            yield $v;
        }
    }
}

$flavors = new PaginatedResultSet(/* args */);

foreach ($flavors->iterate() as &$flavor) {
    $flavor = $flavor->stdClassForApi();
}

This is a feature available in PHP 5.5.

like image 78
Flosculus Avatar answered Oct 15 '22 05:10

Flosculus