|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
[2018-02-28 22:25 UTC] cmb@php.net
-Package: Unknown/Other Function
+Package: Scripting Engine problem
[2021-02-18 10:49 UTC] nikic@php.net
-Status: Open
+Status: Not a bug
[2021-02-18 10:49 UTC] nikic@php.net
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Sun Oct 26 07:00:01 2025 UTC |
Description: ------------ I ran into some very strange behavior while experimenting with static function variables. Static variables in the function scope appear to be resolved using late static binding: the content of the variable in that function is shared amongst all instances of a class, though each subclass gets its own separate variable space. This is pretty logical and works fine. As an example, let's create classes Base => Animal => {Cat,Dog}. Base has a function that describes the class, and caches the result in a static function variable $description. Calling describe() on the three different classes correctly gives us three different results: http://3v4l.org/Qldve However, once you override the describe function in Animal and call parent::describe() from within, it looks like all calling information is lost: the resolution of $description in Base's function scope now always points to Animal's variable space. For example: http://3v4l.org/CcrL8 I would have expected the static function variable and get_called_class() to always refer to the same class/variable space, parent:: or not. Overriding the function in one of the childmost classes like Dog gives an even stranger result: $description is now correctly a separate value in Cat vs Dog, but calling Animal::describe() now uses the value left by its child class Cat?! See: http://3v4l.org/61P72 Test script: --------------- class Base { public static function describe() { echo "--> " . ($calculated = "I am a " . get_called_class() . "\n"); static $cached = null; if ($cached === null) { $cached = $calculated; } return $cached; } } class Animal extends Base { public static function describe() { return 'Hello! ' . parent::describe(); } } class Cat extends Animal { } class Dog extends Animal { } echo Cat::describe(); echo Dog::describe(); echo Animal::describe(); Expected result: ---------------- --> I am a Cat Hello! I am a Cat --> I am a Dog Hello! I am a Dog --> I am a Animal Hello! I am a Animal Actual result: -------------- --> I am a Cat Hello! I am a Cat --> I am a Dog Hello! I am a Cat --> I am a Animal Hello! I am a Cat