php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #66719 Weird behaviour when using get_called_class() with call_user_func()
Submitted: 2014-02-15 18:28 UTC Modified: 2021-07-23 08:39 UTC
From: coolwust at gmail dot com Assigned:
Status: Closed Package: Class/Object related
PHP Version: 5.5.9 OS: linux
Private report: No CVE-ID: None
 [2014-02-15 18:28 UTC] coolwust at gmail dot com
Description:
------------
---
From manual page: http://www.php.net/function.get-called-class
---

B::who(); should has the same result as call_user_func(array('B', 'parent::who')); But it's not.

See the example below.

Test script:
---------------
<?php
class A
{
    public static function who()
    {
        var_dump(get_called_class());
    }
}
class B extends A
{
    public static function who()
    {
        parent::who();
    }
}
B::who();
call_user_func(array('B', 'parent::who'));

?>


Expected result:
----------------
string 'B' (length=1)

string 'B' (length=1)


Actual result:
--------------
string 'B' (length=1)

boolean false


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2014-02-15 21:40 UTC] requinix@php.net
-Status: Open +Status: Not a bug
 [2014-02-15 21:40 UTC] requinix@php.net
array('B', 'parent::who') is not valid: the second element must be the name of a method. array('B', 'who') is the correct form.
 [2014-02-15 22:44 UTC] coolwust at gmail dot com
According to
http://us1.php.net/manual/en/language.types.callable.php

It is valid:

// Type 5: Relative static class method call (As of PHP 5.3.0)
class A {
    public static function who() {
        echo "A\n";
    }
}

class B extends A {
    public static function who() {
        echo "B\n";
    }
}

call_user_func(array('B', 'parent::who')); // A
 [2014-02-16 00:00 UTC] requinix@php.net
-Status: Not a bug +Status: Open
 [2014-02-16 00:00 UTC] requinix@php.net
Interesting. I had no idea that feature existed. Just checked with 5.5.6 and it has the same behavior.

Looks like a bug then as it's not showing any class at all. However I'm not sure which class it should show: could be A if it resolved as B::parent's who, or it could be B if it resolved as B and then parent::who.
 [2014-02-16 01:27 UTC] coolwust at gmail dot com
I was thinking it should output B, but yea, you are right, it simply means B's parent who, but doesn't mention the calling scope. The documentation should show more details on parent::who, what exactly it means.
 [2014-02-16 01:41 UTC] coolwust at gmail dot com
here is a new little test snippet:

class A
{
    public static function who()
    {
        $obj = new static; 
        var_dump($obj);
    }
}
class B extends A
{
    public static function who()
    {
        parent::who();
    }
}
B::who();          //output object(B)[1]
call_user_func(array('B', 'parent::who'));     //output Fatal error: Cannot access static:: when no class scope is active

This means get_called_class() does it job correctly, as it is out of scope and returns null.

However, the doc should gives more details on "parent::who"
 [2015-08-18 18:05 UTC] cmb@php.net
-Status: Open +Status: Verified
 [2015-08-18 18:05 UTC] cmb@php.net
The example calls this feature "relative static class method
call", and as such it should behave identically to calling
A::who() directly, but it doesn't: <https://3v4l.org/vbuVd>.
Interestingly, calling the callable $method directly fails
completely.
 [2021-07-23 08:39 UTC] nikic@php.net
This even causes an assertion failure nowadays:

php: /home/nikic/php/php-src/Zend/zend_vm_execute.h:35335: ZEND_GET_CALLED_CLASS_SPEC_UNUSED_UNUSED_HANDLER: Assertion `!((execute_data)->func)->common.scope' failed.
 [2021-07-23 09:25 UTC] git@php.net
Automatic comment on behalf of nikic
Revision: https://github.com/php/php-src/commit/dfd05da97f72628c5124bfb54976d2c3a02dba82
Log: Fix bug #66719
 [2021-07-23 09:25 UTC] git@php.net
-Status: Verified +Status: Closed
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Mon Dec 30 17:01:29 2024 UTC