Doc #62446 [Opn->Nab]: static call of non-static function breaks context of late static binding

From: Date: Fri, 29 Jun 2012 15:43:54 +0000
Subject: Doc #62446 [Opn->Nab]: static call of non-static function breaks context of late static binding
References: 1  Groups: php.doc.bugs 
Request: Send a blank email to doc-bugs+get-8516@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=62446&edit=1 ID: 62446 Updated by: cataphract@php.net Reported by: picht at eventit dot ag Summary: static call of non-static function breaks context of late static binding -Status: Open +Status: Not a bug Type: Documentation Problem Package: Documentation problem Operating System: ubuntu 2.6.32-41-server PHP Version: 5.3.14 Block user comment: N Private report: N New Comment: I see where the confusion comes from. 'self' works because 'self' refers to the current class 'static' refers to the 'called class'. So in $obj = new Outer(); $obj->testWorking(); $obj->testBroken(); the first call works because 'self' refers to 'Inner'. The twist is that 'static' refers to outer. To understand this, you have to know two things: a) In case of non static method calls, the called class is the class of the object, as I said earlier. b) The class of the object in the body of Inner::NonStaticCalledStaticLate() called from Outer::testBroken() is actually outer. b) may be surprising and is actually a nasty backwards compatibility feature of PHP. If you have E_STRICT on you get a message like "Strict Standards: Non-static method a::bar() should not be called statically, assuming $this from incompatible context". See also http://lxr.php.net/xref/OTHER_IMPLEMENT/hiphop-vm/doc/inconsistencies#97 In any case, this is unrelated to LSB. Previous Comments: ------------------------------------------------------------------------ [2012-06-29 15:33:29] picht at eventit dot ag Because the self keyword works as expected. Try and have a look at the example my coworker posted. ------------------------------------------------------------------------ [2012-06-29 15:28:03] cataphract@php.net I don't know where this confusion comes from. The documentation on php.net/lsb says "[I]n case of non static method calls, [the called class] is the class of the object." ------------------------------------------------------------------------ [2012-06-29 08:15:00] kantert at eventit dot ag This is a simpler example: <?php class Inner { public static function internalStatic() { } public function NonStaticCalledStaticLate() { static::internalStatic(); } public function NonStaticCalledStaticSelf() { self::internalStatic(); } } class Outer { public function testWorking() { Inner::NonStaticCalledStaticSelf(); } public function testBroken() { Inner::NonStaticCalledStaticLate(); } } // Working Inner::NonStaticCalledStaticLate(); // Working Inner::NonStaticCalledStaticSelf(); $obj = new Outer(); // Working $obj->testWorking(); // Broken $obj->testBroken(); // PHP Fatal error: Call to undefined method Outer::internalStatic() in test.php on line 9 echo "Worked"; ?> ------------------------------------------------------------------------ [2012-06-29 08:03:11] picht at eventit dot ag I mixed up "Expected result" and "Actual result". They should be the other way around. Sorry for that! ------------------------------------------------------------------------ [2012-06-29 08:00:28] picht at eventit dot ag Description: ------------ When calling a non-static function statically the late static binding context still points to the calling class context. This should be documented on the static keyword page. Test script: --------------- <?php class a { public static function foo() { echo 'foo a'; } public function bar() { // expecting to call a::foo or b::foo // calls c::foo instead static::foo(); } } class b extends a { public static function foo() { echo 'foo b'; } } class c { public function test() { b::bar(); } public static function foo() { echo 'foo c'; } } $c = new c(); $c->test(); Expected result: ---------------- Documentation suggest b::foo will be called Actual result: -------------- Documentation warns about c::foo getting called ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=62446&edit=1

« previous php.doc.bugs (#8516) next »