The 'flags' field in spl_dllist_it was formerly unused. This means that if one started to
iterate over an SplDoublyLinkedList using 'foreach', and then *changed* the iteration mode
halfway, the 'foreach' loop would start iterating in the opposite direction. Probably this
was not what was intended.
Therefore, use the 'flags' field in spl_dllist_it for iteration via 'foreach'. For explicit
iteration using methods like '::next()' and '::current()', continue to use the flags in
the SplDoublyLinkedList object itself.
spl_dllist_object *object = Z_SPLDLLIST_P(&iter->data);
spl_ptr_llist *llist = object->llist;
- spl_dllist_it_helper_rewind(&iterator->traverse_pointer, &iterator->traverse_position, llist, object->flags);
+ spl_dllist_it_helper_rewind(&iterator->traverse_pointer, &iterator->traverse_position, llist, iterator->flags);
}
/* }}} */
zend_user_it_invalidate_current(iter);
- spl_dllist_it_helper_move_forward(&iterator->traverse_pointer, &iterator->traverse_position, object->llist, object->flags);
+ spl_dllist_it_helper_move_forward(&iterator->traverse_pointer, &iterator->traverse_position, object->llist, iterator->flags);
}
/* }}} */
--- /dev/null
+--TEST--
+Iteration over SplDoublyLinkedList via 'foreach' does not change direction partway
+--FILE--
+<?php
+
+$list = new SplDoublyLinkedList();
+$list->push(1);
+$list->push(2);
+$list->push(3);
+
+/* SplDoublyLinkedList would previously check the iteration mode *each time*
+ it would advance to the next item in a 'foreach' loop
+ This meant that it could move forward, then backward, then forward if the
+ iteration mode was changed in the middle of a loop */
+
+$list->setIteratorMode(SplDoublyLinkedList::IT_MODE_FIFO);
+foreach ($list as $item) {
+ $list->setIteratorMode(SplDoublyLinkedList::IT_MODE_LIFO);
+ echo $item, "\n";
+}
+
+echo "***\n";
+
+$list->setIteratorMode(SplDoublyLinkedList::IT_MODE_LIFO);
+foreach ($list as $item) {
+ $list->setIteratorMode(SplDoublyLinkedList::IT_MODE_FIFO);
+ echo $item, "\n";
+}
+
+
+?>
+--EXPECT--
+1
+2
+3
+***
+3
+2
+1