|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2009-02-13 22:55 UTC] alreece45 at gmail dot com
Description: ------------ When defining properties using constants with parent or self, they are resolved using computed classes instead of defined classes. This behavior appears to have existed since PHP 5.0.5 and still exists in PHP 5.3beta3, a 5.3 CVS snapshot (200902122000), and 5.2 CVS snapshot (200902121200). Someone has brought this up before in php-internals: http://marc.info/?l=php-internals&m=118839969729862&w=2 Reproduce code: --------------- <?php class Father { const my_name = 'Father'; public $name = self::my_name; } class Son extends Father { const my_name = 'Son'; public $daddy = parent::my_name; } class GrandSon extends Son { const my_name = 'Grandchild'; } $older = new GrandSon; echo "{$older->name}\n"; echo "{$older->daddy}\n"; ?> Expected result: ---------------- Father Father Actual result: -------------- Grandchild Son PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Fri Nov 21 05:00:01 2025 UTC |
If the variable is initialized in the constructor then it gives the expected output: function __construct() { $this->name = self::my_name; } So this is specific to initialization in the declaration.Again, not bogus, the value of the property $name depends on the order the objects are created. Even if the expected behavior makes late static binding possible with the self keyword instead of the static keyword. That use is not yet documented, and then the following would become unexpected as it now displays "Father, Father" both times (instead of "Son, Grandson" when an instance of Father is not made). The value of the property should not depend on the order of the objects initiated. New Reproduce Code (Does not replace the previous test script, the original test script output is still the same, and the bug still holds): <?php class Father { const my_name = 'Father'; public $name = self::my_name; } class Son extends Father { const my_name = 'Son'; public $daddy = parent::my_name; } class GrandSon extends Son { const my_name = 'Grandchild'; } $temp = new Father; $older = new GrandSon; echo "{$older->name}\n"; // outputs Father echo "{$older->daddy}\n"; // outputs Father ?>I understand your point with static properties, however: A) because the $name property is defined in Father, it should be using the "self" as seen from Father (as happens when you use the constant from a method like __construct). If this is not the expected case, the documentation should be clarified that using self changes depending on the context. The following code should ALWAYS set the property to the same value when defined in the same class (regardless of child classes). 1) public $var = self::someConstant; 2) function __construct() { $this->var = self::someConstant; } B) Because both class constants and static properties and methods are tied to a class definition. It should be documented with class constants whether or not they are static. C) I incorrectly concluded when writing the test case that the object instance affected non-static properties (I encountered the bug in a more complex code-base). However, it does affect the values when static properties are used (another example included below). <?php class Father { const my_name = 'Father'; public static $name = self::my_name; } class Son extends Father { const my_name = 'Son'; public static $daddy = parent::my_name; } class GrandSon extends Son { const my_name = 'Grandchild'; } // new Father(); // uncommenting this line affects output echo Grandson::$name . "\n"; // outputs Grandchild echo Grandson::$daddy . "\n"; // outputs Son ?>