If an Iterator has been partially or fully traversed, calling iterator_count() will return the remaining number of elements or 0.
Incorrect Example:
<span><span><span class="hljs-variable">$it</span></span><span> = </span><span><span class="hljs-keyword">new</span></span><span> </span><span><span class="hljs-built_in">ArrayIterator</span></span><span>([</span><span><span class="hljs-number">1</span></span><span>, </span><span><span class="hljs-number">2</span></span><span>, </span><span><span class="hljs-number">3</span></span><span>, </span><span><span class="hljs-number">4</span></span><span>]);
</span><span><span class="hljs-variable">$it</span></span><span>-></span><span><span class="hljs-title function_ invoke__">next</span></span><span>(); </span><span><span class="hljs-comment">// Moved one step</span></span><span>
</span><span><span class="hljs-variable">$count</span></span><span> = </span><span><span class="hljs-title function_ invoke__">iterator_count</span></span><span>(</span><span><span class="hljs-variable">$it</span></span><span>); </span><span><span class="hljs-comment">// Returns 3 instead of 4</span></span><span>
</span></span>
Solution:
Reset the iterator before calling iterator_count():
<span><span><span class="hljs-variable">$it</span></span><span> = </span><span><span class="hljs-keyword">new</span></span><span> </span><span><span class="hljs-built_in">ArrayIterator</span></span><span>([</span><span><span class="hljs-number">1</span></span><span>, </span><span><span class="hljs-number">2</span></span><span>, </span><span><span class="hljs-number">3</span></span><span>, </span><span><span class="hljs-number">4</span></span><span>]);
</span><span><span class="hljs-variable">$it</span></span><span>-></span><span><span class="hljs-title function_ invoke__">rewind</span></span><span>(); </span><span><span class="hljs-comment">// Reset pointer</span></span><span>
</span><span><span class="hljs-variable">$count</span></span><span> = </span><span><span class="hljs-title function_ invoke__">iterator_count</span></span><span>(</span><span><span class="hljs-variable">$it</span></span><span>); </span><span><span class="hljs-comment">// Returns 4</span></span><span>
</span></span>
iterator_count() fully traverses the iterator. If the dataset is large or the iterator contains complex logic, this may cause significant performance problems.
Example:
<span><span><span class="hljs-variable">$it</span></span><span> = </span><span><span class="hljs-keyword">new</span></span><span> </span><span><span class="hljs-built_in">InfiniteIterator</span></span><span>(</span><span><span class="hljs-keyword">new</span></span><span> </span><span><span class="hljs-built_in">ArrayIterator</span></span><span>([</span><span><span class="hljs-number">1</span></span><span>, </span><span><span class="hljs-number">2</span></span>, </span><span><span class="hljs-number">3</span></span>]));
</span><span><span class="hljs-variable">$count</span></span><span> = </span><span><span class="hljs-title function_ invoke__">iterator_count</span></span><span>(</span><span><span class="hljs-variable">$it</span></span><span>); </span><span><span class="hljs-comment">// Will never finish</span></span><span>
</span></span>
Solution:
Ensure the iterator has not been partially traversed, or reset the pointer using rewind() before calling.
Avoid calling iterator_count() on non-reusable iterators (like generators). Instead, convert them using iterator_to_array() before counting.
Do not use this function on infinite or resource-heavy iterators. Always evaluate the execution cost first.
Write test code to validate behavior, especially when working with Traversable objects returned by third-party libraries.