php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Doc Bug #62446 static call of non-static function breaks context of late static binding
Submitted: 2012-06-29 08:00 UTC Modified: 2012-06-29 15:43 UTC
From: picht at eventit dot ag Assigned:
Status: Not a bug Package: Documentation problem
PHP Version: 5.3.14 OS: ubuntu 2.6.32-41-server
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: picht at eventit dot ag
New email:
PHP Version: OS:

 

 [2012-06-29 08:00 UTC] 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

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2012-06-29 08:03 UTC] 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:15 UTC] 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 15:28 UTC] 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 15:33 UTC] 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:43 UTC] cataphract@php.net
-Status: Open +Status: Not a bug
 [2012-06-29 15:43 UTC] cataphract@php.net
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.
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Fri Mar 14 15:01:30 2025 UTC