0

Already I extended and implemented from SPL iterator.
But if I want to use it, I should use it on a foreach.
I tried to use it in a while like this:

$news = new testClass();

while( $row = $news )
    echo $row["name"];

It will create an infinite loop !
But with foreach, it works fine!

Here is top of my class:

class testClass implements \Iterator

Where is the mistake ?

2
  • 2
    Using a while loop is more of a C-style iterator than the iterator you're thinking of. You need to implement Iterator's methods and it should then work with a foreach loop. Commented Feb 3, 2013 at 12:47
  • 1
    Are you trying to iterate over the public attributes in the $news object? Commented Feb 3, 2013 at 12:47

3 Answers 3

1

Fist, bravo on using the SPL classes for this type of 'standard' problem. Too often have I seen inexperienced/sloppy developers (or even good ones that simply don't think ahead) reinvent the wheel in these types of situations.

You're missing some very important details about the implementation of the iterator interface.

see PHP:Iterator - Manual for more information, and the reference implementation from below.

First, you need to implement the, rewind, current, key, next, and valid functions. the reference implementation looks like this:

class myIterator implements Iterator {
    private $position = 0;
    private $array = array(
        "firstelement",
        "secondelement",
        "lastelement",
    );  

    public function __construct() {
        $this->position = 0;
    }

    function rewind() {
        var_dump(__METHOD__);
        $this->position = 0;
    }

    function current() {
        var_dump(__METHOD__);
        return $this->array[$this->position];
    }

    function key() {
        var_dump(__METHOD__);
        return $this->position;
    }

    function next() {
        var_dump(__METHOD__);
        ++$this->position;
    }

    function valid() {
        var_dump(__METHOD__);
        return isset($this->array[$this->position]);
        }
    }
)

And the code for traversing that implementation looks like this:

$it = new myIterator;

foreach($it as $key => $value) {
    var_dump($key, $value);
    echo "\n";
}
Sign up to request clarification or add additional context in comments.

2 Comments

+1! Thanks for your answer. I already have this style. If you back on my question, I said it is top of my class!
I caught that, but it doesn't tell me that you have implemented the necessary functions. The answer to your question, then, is covered with the second bit of example code (using foreach instead of for).
1

foreach is language construct that iterates through all elements. while executes block of code until given condition is true. To make it work you have to use your own function that checks for valid key and returns current element.

Comments

0

Finally I created a simple example of this:

<?php

/**
 * @author Soroush Khosravi
 * @copyright 2013
 */
class _Iterator
{
    private $array;

    public function setArray(array $data)
    {
        $this->array = $data;
    }

    public function reader()
    {
        if (is_null($this->array))
            return false;

        $elem = array_shift($this->array);
        if (count ($this->array) > 0)
            return $elem;
        return false;
    }
}

Class child extends _Iterator
{
    function execute()
    {
        $this->setArray(array(1,2,3,4,5,6));
        return $this;
    }
}
$obj = new child;
$obj = $obj->execute();
while($row = $obj->reader())
    echo $row;

?>

5 Comments

No need to answer your own question. And keep in mind that this will fail for any falsy value in your array (ie try putting 0 between 3 and 4), so better stick with foreach.
@dev-null-dweller I don't remember that I asked about foreach ! I was looking for this form and now this is my answer and I think it is true :)
I'm just saying that you might have trouble with some values with this construct, that's all.
Regardless of the form of the answer that you're looking for, using foreach is a better, less error-prone way of approaching this problem. In this situation not using foreach is like using an array of characters instead of a string. Answering your own question with an answer that's less well thought out than already-posted answers is silly.
Thanks for all comments :x But I use it for mysql and I don't think any element on the array will be false or equivalent of false...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.