Bug #77985 [Opn->Nab]: Wrong resolution of "Late Static Binding" after self::method()

From: Date: Mon, 09 Mar 2020 10:26:55 +0000
Subject: Bug #77985 [Opn->Nab]: Wrong resolution of "Late Static Binding" after self::method()
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-225970@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=77985&edit=1 ID: 77985 Updated by: nikic@php.net Reported by: dev at mabe dot berlin Summary: Wrong resolution of "Late Static Binding" after self::method() -Status: Open +Status: Not a bug Type: Bug Package: Class/Object related Operating System: Linux PHP Version: Irrelevant Block user comment: N Private report: N New Comment: 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. Previous Comments: ------------------------------------------------------------------------ [2020-03-09 10:23:56] 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 ------------------------------------------------------------------------ [2019-05-07 19:33:51] dev at mabe dot berlin Sorry in my first sentence I mean "if it got called using self::method()" ------------------------------------------------------------------------ [2019-05-07 19:31:40] 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 ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=77985&edit=1

« previous php.bugs (#225970) next »