]> granicus.if.org Git - php/commitdiff
Fix implementation of Iterator interface
authorNikita Popov <nikic@php.net>
Thu, 26 Jul 2012 15:07:24 +0000 (17:07 +0200)
committerNikita Popov <nikic@php.net>
Thu, 26 Jul 2012 15:13:25 +0000 (17:13 +0200)
It looks like you have to implement the Iterator interface *before*
assigning get_iterator. Otherwise the structure for user iterators isn't
correctly zeroed out.

Additionaly I'm setting class_entry->iterator_funcs.funcs now. Not sure if
this is strictly necessary, but better safe than sorry ;)

Zend/tests/generators/generator_in_multipleiterator.phpt [new file with mode: 0644]
Zend/zend_generators.c

diff --git a/Zend/tests/generators/generator_in_multipleiterator.phpt b/Zend/tests/generators/generator_in_multipleiterator.phpt
new file mode 100644 (file)
index 0000000..611dbc9
--- /dev/null
@@ -0,0 +1,37 @@
+--TEST--
+Generators work properly in MultipleIterator
+--FILE--
+<?php
+
+function gen1() {
+    yield 'a';
+    yield 'aa';
+}
+
+function gen2() {
+    yield 'b';
+    yield 'bb';
+}
+
+$it = new MultipleIterator;
+$it->attachIterator(gen1());
+$it->attachIterator(gen2());
+
+foreach ($it as $values) {
+    var_dump($values);
+}
+
+?>
+--EXPECT--
+array(2) {
+  [0]=>
+  string(1) "a"
+  [1]=>
+  string(1) "b"
+}
+array(2) {
+  [0]=>
+  string(2) "aa"
+  [1]=>
+  string(2) "bb"
+}
index d7ffb3055a6a5b4646f938e372a281df68c4edb7..716b0a782edd13c6707573b2bcc7e1188e743533 100644 (file)
@@ -759,9 +759,11 @@ void zend_register_generator_ce(TSRMLS_D) /* {{{ */
        zend_ce_generator = zend_register_internal_class(&ce TSRMLS_CC);
        zend_ce_generator->ce_flags |= ZEND_ACC_FINAL_CLASS;
        zend_ce_generator->create_object = zend_generator_create;
-       zend_ce_generator->get_iterator = zend_generator_get_iterator;
 
+       /* get_iterator has to be assigned *after* implementing the inferface */
        zend_class_implements(zend_ce_generator TSRMLS_CC, 1, zend_ce_iterator);
+       zend_ce_generator->get_iterator = zend_generator_get_iterator;
+       zend_ce_generator->iterator_funcs.funcs = &zend_generator_iterator_functions;
 
        memcpy(&zend_generator_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
        zend_generator_handlers.get_constructor = zend_generator_get_constructor;