|  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #69586 Resolution of static function variables not using forwarded calling information
Submitted: 2015-05-06 15:05 UTC Modified: 2018-02-28 22:25 UTC
From: php at lvl dot fastmail dot com Assigned:
Status: Open Package: Scripting Engine problem
PHP Version: 5.6.8 OS:
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
Block user comment
Status: Assign to:
Bug Type:
From: php at lvl dot fastmail dot com
New email:
PHP Version: OS:


 [2015-05-06 15:05 UTC] php at lvl dot fastmail dot com
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:

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:

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:

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


Add a Patch

Pull Requests

Add a Pull Request


AllCommentsChangesGit/SVN commitsRelated reports
 [2018-02-28 22:25 UTC]
-Package: Unknown/Other Function +Package: Scripting Engine problem
PHP Copyright © 2001-2021 The PHP Group
All rights reserved.
Last updated: Wed Jan 20 16:01:23 2021 UTC