ZF-6995: Zend_config : toArray conflict with iterator implements.
Description
Function "toArray()" is created with a foreach on "_data". Interface "iterator" is implemented with : "next($this->_data)" and others functions of iterator directly on "_data".
My problem is function "toArray()" which is in conflict with the iterator interface. For fix that , we must create a clone of object and after we can use "toArray()".
But function "toArray()" should be NOT in conflict with iterator ?
For me, the problem is not "toArray()" but the implement of "Iterator". And is just when we want used "toArray()" AND iterator in same time on same object.
This problem could be apply to all classes with iterator and "toArray()". But I don't know if it's a usage problem or a bug.
Nicolas CHOTIN.
Comments
Posted by Rob Allen (rob) on 2009-06-12T06:59:39.000+0000
Would you mind providing the code you're using along with the results you're getting and the results you are expecting?
Thanks,
Rob...
Posted by julien PAULI (doctorrock83) on 2009-06-12T11:07:49.000+0000
Foreach() uses the array directly and thus, the internal array iterator and not Zend_Config's iterator.
Could you provide a use case ?
Posted by Tomoaki Kosugi (noopable) on 2009-06-13T01:08:54.000+0000
Hi I was put in a similar situation. toArray breaks iteration. At between before and after toArray, a behavior of valid and current is amusing.
Here is repro-code
2nd sample should be " not valid " or "valid? int(1)"
One Solution is clone $this->_data before "foreach($this->_data" In Zend_Config::toArray() .
Posted by CHOTIN Nicolas (nicochot) on 2009-06-15T07:38:48.000+0000
In my case it's a controller for testing. I have create a config file with a "value" for config and a "value" for testing :
test.c1.regexp = ^/index/test test.c1.test = /index/test test.c2.regexp = ^/index/test1 test.c2.test = /index/test1
The initialization of object is in loop of tests, because this object is initialized only when used. But in real context we don't have a loop on same object "Zend_Config".
So for me it's a usage problem but it's interesting to add a warning in documentation mostly if Zend_Config it's not alone class in this case.
Posted by julien PAULI (doctorrock83) on 2009-06-15T09:25:43.000+0000
Ok I see.
toArray() works directly on the _data array, and so does the iterator. When calling toArray(), a foreach loop is used to iterate throught _data, that foreach loop first calls rewind() internaly , and then iterates. The problem is that the foreach loop leaves the array iterator at an undefinied position (that's why rewind() is called by foreach before the iteration). Then when you call current() on your object, it just says it doesn't have a current value.
To see that, create a getIndex() method in Zend_Config, which return $_index; and try this :
The patch is easy, trigger the internal PHP copy-on-write system to make foreach loop over a copy of the _data array, and not the real _data. Just add :
Even not using the new $data variable created, it increments the internal refcount on the _data structure, making foreach use a copy of it ;-)
Posted by Rob Allen (rob) on 2009-06-16T02:10:12.000+0000
julien,
Fancy writing a unit test and then patching?
Regards,
Rob...
Posted by julien PAULI (doctorrock83) on 2009-06-16T04:07:50.000+0000
I'm on it
Posted by julien PAULI (doctorrock83) on 2009-06-16T12:20:57.000+0000
Fixed in SVN r16090