Edit report at https://bugs.php.net/bug.php?id=63976&edit=1
ID: 63976 Patch added by: m...@php.net Reported by: don at smugmug dot com Summary: Parent class incorrectly using child constant in class property Status: Open Type: Bug Package: Class/Object related Operating System: Ubuntu 12.04 PHP Version: 5.4.10 Block user comment: N Private report: N New Comment: The following patch has been added/updated: Patch Name: update_class_constants Revision: 1360863036 URL: https://bugs.php.net/patch-display.php?bug=63976&patch=update_class_constants&revision=1360863036 Previous Comments: ------------------------------------------------------------------------ [2013-01-12 03:53:33] don at smugmug dot com 'Have a preference' should have said 'I have a preference'. Certainly not intending for PHP to add some new INI option or something to change how static:: and self:: behave. :) Also, have confirmed this on 5.4.4 and CentOS in addition to Ubuntu and 5.4.10, both with and without extensions like APC loaded. ------------------------------------------------------------------------ [2013-01-12 03:51:21] don at smugmug dot com Description: ------------ Class properties that rely on potentially inherited class constants have unpredictable behavior. Since PHP doesn't support Child class properties referencing static values like static::CONST, the meaning of self::CONST is ambiguous. One of two things should happen: 1. It should use the value defined in the actual class in question (like self:: is used throughout the rest of PHP). 2. It should treat self:: in this case, since it's compile-time and not late static binding, like static:: and walk the inheritance tree, delivering the result for the Child class. Option #1 seems the most sane, but PHP often behaves like it intends #2 to work. But not always... In the provided examples, 'brokenA.php' behaves like #1, above, while 'brokenB.php' and 'brokenC.php' behave like #2. The only thing that's changed is the order in which the classes are require()'d. In a complex script, with autoloaders, class instantiation order isn't predictable, of course, resulting in unpredictable results. Test script: --------------- Example code: https://github.com/onethumb/php-parent-child-constant-bug Expected result: ---------------- Consistent results for Baz->table. Either 'foo' or 'baz' 100% of the time, rather than mixed up depending on require() order. Have a preference for adding static::CONST to PHP and making self::CONST behave like self:: does in the rest of the language (resulting in Baz->table == 'baz' in the examples if we used static::CONST), but if that's not preferable for some reason, self::CONST should probably behave like self:: everywhere else (resulting in Baz->table == 'foo' in the examples). Actual result: -------------- brokenA.php: Bar Object ( [table] => bar ) Baz Object ( [table] => foo ) brokenB.php: Bar Object ( [table] => bar ) Baz Object ( [table] => baz ) brokenC.php: Baz Object ( [table] => baz ) Bar Object ( [table] => bar ) Baz Object ( [table] => baz ) ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=63976&edit=1