php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #77985 Wrong resolution of "Late Static Binding" after self::method()
Submitted: 2019-05-07 19:31 UTC Modified: 2020-03-09 10:26 UTC
From: dev at mabe dot berlin Assigned:
Status: Not a bug Package: Class/Object related
PHP Version: Irrelevant OS: Linux
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: dev at mabe dot berlin
New email:
PHP Version: OS:

 

 [2019-05-07 19:31 UTC] dev at mabe dot berlin
Description:
------------
Wrong resolution of the referenced class that was initially called (Late Static Binding) if it gets called using static::method().

Both, static::class as well as get_called_class() result into the wrong class name.

Simplified explanation from test script:

1. calling "B:call()"

2. -> calling "self::getStaticClass()" defined in "A::call"
  This should get resolved to "A::getStaticClass()"

3. -> returning "static::class"
  This should get resolved to "A:class" as it was called by "A::getStaticClass()"


Test script:
---------------
<?php

class A {
    static function getStaticClass(){ return static::class; }
    static function getCalledClass() { return get_called_class(); }
    static function call(){
        $self = self::class;
        echo $self;
        echo $self::getStaticClass();
        echo $self::getCalledClass();
        echo self::getStaticClass();
        echo self::getCalledClass();

        echo PHP_EOL;

        $static = static::class;
        echo $static;
        echo $static::getStaticClass();
        echo $static::getCalledClass();
        echo static::getStaticClass();
        echo static::getCalledClass();

        echo PHP_EOL;
        
        $calledClass = get_called_class();
        echo $calledClass;
        echo $calledClass::getStaticClass();
        echo $calledClass::getCalledClass();

        echo PHP_EOL;
    }
}

class B extends A {}

echo 'A:call()', PHP_EOL;
A::call();

echo 'B:call()', PHP_EOL;
B::call();

Expected result:
----------------
A:call()
AAAAA
AAAAA
AAA
B:call()
AAAAA
BBBBB
BBB

Actual result:
--------------
A:call()
AAAAA
AAAAA
AAA
B:call()
AAABB      <- The last two cases should resolve to A instead of B
BBBBB
BBB

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2019-05-07 19:33 UTC] dev at mabe dot berlin
-Summary: Wrong resolution of "Late Static Binding" after static::method() +Summary: Wrong resolution of "Late Static Binding" after self::method()
 [2019-05-07 19:33 UTC] dev at mabe dot berlin
Sorry in my first sentence I mean "if it got called using self::method()"
 [2020-03-09 10:23 UTC] php at yopmail dot com
See https://externals.io/message/108895#108904 for why that's intended behavior.

Shorter example:

```
<?php

class A {
    public static function test() {
        A::f();
        self::f();
        static::f();
    }
    protected static function f() {
        echo 'A, ', static::class, PHP_EOL;
    }
}

class B extends A {
    protected static function f() {
        echo 'B, ', static::class, PHP_EOL;
    }
}

B::test();
```

Output:
-------
A, A
A, B
B, B
 [2020-03-09 10:26 UTC] nikic@php.net
-Status: Open +Status: Not a bug
 [2020-03-09 10:26 UTC] nikic@php.net
As explained in the linked thread, this behavior is intentional, so I'm closing this bug.

I think the main use-case here is inheriting LSB scope when calling parent::method() -- the self::method() case is more a consistency consideration.
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Mon Jun 16 06:01:34 2025 UTC