You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The place where interface implementation handlers is called is
currently ill-defined: If the class implements interfaces itself,
the handlers for both the parent interfaces and the new interfaces
will be called after all methods are registered (post trait use).
If the class does not implement interfaces, then the parent
interface handlers are called early during inheritance (before
methods are inherited).
This commit moves the calls to always occur after all methods are
available. For userland classes this will be post trait import,
at the time where interfaces get implemented (whether the class
itself defines additional interfaces or not). For internal classes
it will be at the end of inheritance, as internal class declarations
do not have proper finalization.
This allows us to simplify the logic for implementing the magic
Iterator / IteratorAggregate interfaces. In particularly we can
now also automatically detect whether an extension of
IteratorAggregate can safely reuse a custom get_iterator handler,
or whether it needs to switch to the userland mechanism. The
Iterator case continues to rely on ZEND_ACC_REUSE_GET_ITERATOR
for this purpose, as a wholesale replacement is not possible there.
/* Note that new interfaces can be added during this loop due to interface inheritance.
1538
1527
* Use num_interfaces rather than ce->num_interfaces to not re-process the new ones. */
1539
1528
for (; i<num_interfaces; i++) {
@@ -2459,6 +2448,8 @@ ZEND_API int zend_do_link_class(zend_class_entry *ce, zend_string *lc_parent_nam
2459
2448
}
2460
2449
if (interfaces) {
2461
2450
zend_do_implement_interfaces(ce, interfaces);
2451
+
} elseif (parent&&parent->num_interfaces) {
2452
+
zend_do_inherit_interfaces(ce, parent);
2462
2453
}
2463
2454
if ((ce->ce_flags& (ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_INTERFACE|ZEND_ACC_TRAIT|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) ==ZEND_ACC_IMPLICIT_ABSTRACT_CLASS) {
if ((ce->ce_flags& (ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_INTERFACE|ZEND_ACC_TRAIT|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) ==ZEND_ACC_IMPLICIT_ABSTRACT_CLASS) {
0 commit comments