Hi all, There has been some discussion on this list about late static binding and the 'self' & 'parent' keywords. I'm looking to understand the meaning of self:: and parent:: when used in the declaration of an inherited class property or constant.
Based on discussions here and on comments to bugs like http://bugs.php.net/bug.php?id=30934, my understanding is that self:: should be bound statically at compile time. Therefore, in the example below, I would naively assume that self:: would always refer to class A. <?php class A { const MY_CONST = 'MY_CONST_A'; public static $inheritedStatic = self::MY_CONST; public $inheritedProp = self::MY_CONST; const INHERITED_CONST = self::MY_CONST; } class B extends A { const MY_CONST = 'MY_CONST_B'; } ?> However, this is not the case. It seems that at compile time, the engine flags class properties/constants that depend on class constants. They are then subject to a one-off re-evaluation at execution time. The flagging is done by setting the zval 'type' field to IS_CONSTANT, IS_CONSTANT_ARRAY or IS_CONSTANT_INDEX. The re-evaluation is done in zend_update_class_constants(). When self:: is involved, the result of this re-evaluation is not always intuitive imho, and appears to contradict the idea that self:: is bound at compile time. See this test case for an illustration: http://pastebin.com/f1d93fb2e To summarize the behaviour exhibited by that test case: 1. An inherited static property's value depends on the order in which classes are touched at execution time. The meaning of 'self' is fixed, but depends on the scope in which zend_update_class_constants() is first executed. Removing line 15 changes the outcome of the test. 2. An inherited instance property's value depends on the instantiated class. When accessing the inherited property through an instance of A, 'self' is taken to mean A. When accessing it through an instance of B, 'self' is taken to mean 'B'. Presumably, this is because the property is propagated to the subclass before its default value is evaluated. 3. Similarly to 2, an inherited constant's value depends on how it is accessed. When accessing A::INHERITED_CONST, 'self' is taken to mean A; when accessing B::INHERITED_CONST, 'self' is taken to mean B. Is this as expected? I would argue that at least point 1 is a bug, but would appreciate opinions before I investigate further. (The exact same issues apply when using parent::. See this testcase: http://pastebin.com/f249a0e8c ) Regards, Robin -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php