1

I'm trying to iterate an array with next() current() and rewind(): is there a simple way to know when current pointer is arrived at the end ?

I just seen that when i'm at the end next() and current() returns both FALSE, but this also append when the array cells contain the FALSE boolean value.

edit: of course sorry to not have specified that it's a numerical array. I use it to and i'm trying to do a wordpress like

while ( have_post() )
      do_post()

but the origin can be both an array or a PDOStatement, like the follow:

class Document implements ContentGetter{
   private $array_or_rs;
   private $currentval;

   public function have_content() { //part of interface
      if( is_a($this->$array_or_rs, 'PDOStatement') ) {
          $result = PDOStatement-fetch();
          _do_things_
      } else {
          $result = next($this->$array_or_rs);
      }
      $this->$currentval = $result;
      return $result === FALSE;
   }

   public function get_content() { //part of interface
      return $this->$currentval;
   }
}
3
  • 2
    Why? Why are you reinventing the wheel? Homework maybe? :-) Commented Jan 28, 2014 at 21:50
  • Read on: Iterator pattern Commented Jan 28, 2014 at 21:51
  • imo the edit is too radical. I suggest to ask a new question. Commented Jan 28, 2014 at 22:26

2 Answers 2

3

Can I iterate over an array without using a foreach loop in PHP?

Here you go:

$array = array(NULL, FALSE, 0);
while(list($key, $value) = each($array)) {
    var_dump($value);
}

Output:

NULL
bool(false)
int(0)

next() and current() can't be used because there is no way to determine if a FALSE return value means a FALSE element or the end of the array. (As you've observed). However, you can use the function each(), as it will return an array containing the current key and value or FALSE at the end of the array. After it has been executed, the current-pointer will be set to the next element.

I must admit that I've not used that since > 10 years. :) However it is a basic PHP function and it still works.

How to implement the WordPres-like ContentGetter interface?

I would make usage of PHP's Iterator concept. You can wrap either the array in to an ArrayIterator or the PDOStatement into a PDOStatementIterator. While this first is a built-in class of PHP, the latter has to be written. Alternatively you can use this one (looks good, but contains more functionality than required for this task)

Based on that, the Document class should look like this:

class Document implements ContentGetter {

    /**
     * @var Iterator
     */
    protected $iterator;

    /**
     * @param array|PDOStatement $stmtOrArray
     */
    public function __construct($stmtOrArray) {
        if(is_a($stmtOrArray, 'PDOStatement')) {
            $this->iterator = new PDOStatementIterator($stmtOrArray);
        } else if(is_array($stmtOrArray)) {
            $this->iterator = new ArrayIterator($stmtOrArray);
        } else {
            throw new Exception('Expected array or PDOStatement');
        }
    }

    /**
     * Wrapper for Iterator::valid()
     */
    public function have_content() {
        return $this->iterator->valid();
    }

    /**
     * Wrapper for Iterator::current() + Iterator::next()
     */
    public function get_content() {
        $item = $this->iterator->current();
        $this->iterator->next();
        return $item;
    }
}

Tests:

// Feed Document with a PDOStatement
$pdo = new PDO('mysql:host=localhost', 'user', 'password');
$result = $pdo->query('SELECT 1 UNION SELECT 2'); // stupid query ...

$doc = new Document($result);
while($doc->have_content()) {
    var_dump($doc->get_content());
}

.

// Feed Document with an array
$doc = new Document(array(1, 2, 3));
while($doc->have_content()) {
    var_dump($doc->get_content());
}
Sign up to request clarification or add additional context in comments.

Comments

1

you could compare key() to sizeof($my_array)

1 Comment

This is only true for numeric arrays.

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.