Defining a __toString() method was having no effect when concatenating
the object. This was because the cast_object() handler would ignore
__toString().
Using echo() directly would actually use __toString(), but this was a
bug: the ECHO handler would try zend_std_cast_object_tostring() before
cast_object(), but cast_object() should have priority as
zend_std_cast_object_tostring() assumes an object with a
zend_class_entry.
The solution was already introduced in 5.4 by Etienne Kneuss and
Pierre but wasn't merged back into 5.3 . SplFileObject should
not be used with directories. So just putting together all the
necessary pieces from 5.4
Turns out I'd forgotten to also update the destructor for the iterator
returned by DirectoryIterator.
The iterator for DirectoryIterator maintains the same ->current pointer
throughout its existence (the DirectoryIterator itself) and returns it
(the same object) everytime a value is requested from the iterator.
Moving forward the iterator only changes the object. Previous code
added two references to the object in get_iterator on the account of
1) the iterator memory living in its DirectoryIterator object and
2) the object being stored in iterator->current. This seems to be
unnecessary. Iterators are not responsible for incrementing the refcount
of the values they yield, that's up to the caller (the engine). What
matters for the iterator is that the object exists as long as the
iterator exists and this can be guaranteed by incremented the refcount
only once. Consequently, I only add one reference in get_iterator
(and reclaim it in the iterator destructor).
- Extented strategy to remaining the classes on spl_directory.c, even those that don't crash.
- UPGRADING.
- Better bug54384.phpt, with all the classes covered.
not called.
#Merge to 5.3 pending (slight BC break on AppendIterator, as it's no
#longer possible to defer the call to the parent constructor until
#after the constructor is performed).
#Bugs fixed in an atypical way for SPL. The parent constructor call
#check is performed at construction time by using a wrapper constructor
#instead of a check on the beginning of each instance method.
#Perhaps this should be uniformized in trunk; this method was mainly
#applied only to the ones crashing, except a few iterators (at least
#AppendIterator and RecursiveIteratorIterator).