title: How should PHP's Iterator methods valid(), current(), and next() behave?
body: <p>I am using PHP 5.3.6 from <a href="http://www.mamp.info" rel="noreferrer">MAMP</a>.</p>
  
  <p>I have a use case where it would be best to use PHP's <code>Iterator</code> interface methods, <code>next()</code>, <code>current()</code>, and <code>valid()</code> to iterate through a collection. A <code>foreach</code> loop will NOT work for me in my particular situation. A simplified while loop might look like </p>
  
  <pre><code>&lt;?php
  while ($iter-&gt;valid()) {
    // do something with $iter-&gt;current()
    $iter-&gt;next();
  }
  </code></pre>
  
  <p>Should the above code always work when $iter implements PHP's <code>Iterator</code> interface? How does PHP's <code>foreach</code> keyword deal with Iterators?</p>
  
  <p>The reason I ask is that the code I am writing may be given an <code>ArrayIterator</code> or a <code>MongoCursor</code>. Both implement PHP's <code>Iterator</code> interface but they behave differently. I would like to know if there is a bug in PHP or PHP's Mongo extension.</p>
  
  <p><code>ArrayIterator::valid()</code> returns true <em>before</em> any call to <code>next()</code> -- immediately after the <code>ArrayIterator</code> is created.</p>
  
  <p><code>MongoCursor::valid()</code> only returns true <em>after</em> the first call to <code>next()</code>. Therefore the while loop above will never execute.</p>
  
  <p>At risk of being verbose, the following code demonstrates these assertions:</p>
  
  <pre><code>&lt;?php
  
  // Set up array iterator
  $arr = array("first");
  $iter = new \ArrayIterator($arr);
  
  // Test array iterator
  echo(($iter-&gt;valid() ? "true" : "false")."\n"); // Echoes true
  var_dump($iter-&gt;current()."\n");                // "first"
  $iter-&gt;next();
  echo(($iter-&gt;valid() ? "true" : "false")."\n"); // Echoes false
  
  
  // Set up mongo iterator
  $m = new \Mongo();
  $collection = $m-&gt;selectDB("iterTest")-&gt;selectCollection("mystuff");
  $collection-&gt;drop(); // Ensure collection is empty
  $collection-&gt;insert(array('a' =&gt; 'b'));
  $miter = $collection-&gt;find(); // should find one object
  
  // Test mongo iterator
  echo(($miter-&gt;valid() ? "true" : "false")."\n"); // Echoes false
  
  $miter-&gt;next();
  
  echo(($miter-&gt;valid() ? "true" : "false")."\n"); // Echoes true
  var_dump($miter-&gt;current());                     // Array(...)
  </code></pre>
  
  <p>Which implementation is correct? I found little documentation to support either behavior, and the official PHP documentation is either ambiguous or I'm reading it wrong. The <a href="http://www.php.net/manual/en/iterator.valid.php" rel="noreferrer">doc for</a> <code>Iterator::valid()</code> states:</p>
  
  <blockquote>
    <p>This method is called after Iterator::rewind() and Iterator::next() to check if the current position is valid.</p>
  </blockquote>
  
  <p>This would suggest that my while loop should <em>first</em> call <code>next()</code>.</p>
  
  <p>Yet the <a href="http://www.php.net/manual/en/iterator.next.php" rel="noreferrer">PHP documentation for</a> <code>Iterator::next</code> states:</p>
  
  <blockquote>
    <p>This method is called after each foreach loop.</p>
  </blockquote>
  
  <p>This would suggest that my while loop is correct as written.</p>
  
  <p>To summarize - how should PHP iterators behave? </p>