Bug->Doc #76028 [Opn->Ver]: call_user_func($a) and $a() behave differently

[email protected]
Newsgroups php.doc.bugs
Message-ID <[email protected]>
Edit report at https://bugs.php.net/bug.php?id=76028&edit=1

 ID:                 76028
 Updated by:         [email protected]
 Reported by:        bburnichon at gmail dot com
 Summary:            call_user_func($a) and $a() behave differently
-Status:             Open
+Status:             Verified
-Type:               Bug
+Type:               Documentation Problem
 Package:            Scripting Engine problem
 Operating System:   Linux
 PHP Version:        7.1
 Block user comment: N
 Private report:     N

 New Comment:

> I just wished I knew this before.

So yes, this is actually a documentation problem.

Note that as of PHP 8.1.0 you can use

    self::foo(...)

which is even better, since that callable is callable everywhere.
For previous PHP versions, you can use the more verbose

    Closure::fromCallable([self::class, 'foo'])

to have the same benefit.


Previous Comments:
------------------------------------------------------------------------
[2018-02-28 17:54:36] bburnichon at gmail dot com

Yes, that's what I've done once I discovered the issue. I just wished I knew this before. I've learnt it the hard way while refactoring an old class which was calling 

```
$method = // Method from user input
$callable = ['self', $method];
if (is_callable($callable)) {
  call_user_func($callable);
}
```

to 

```
$method = // Whitelisted method
$callable = [self::class, $method];
$callable();
```

------------------------------------------------------------------------
[2018-02-28 17:39:09] [email protected]

FWIW: don't use the string 'self', but rather self::class,
see <https://3v4l.org/Xkkuf>.

------------------------------------------------------------------------
[2018-02-28 14:58:25] [email protected]

Related: https://wiki.php.net/rfc/consistent_callables

------------------------------------------------------------------------
[2018-02-28 14:38:40] bburnichon at gmail dot com

Checked versions having the issue with 3v4l.org: https://3v4l.org/Ssgep

------------------------------------------------------------------------
[2018-02-28 14:33:43] bburnichon at gmail dot com

Description:
------------
A callable can be defined as an array containing class and method.

Calling call_user_func() with such an array has no issue.
If you try to use the array as a callable, then 'self' loose its special meaning and an error is triggered saying class self does not exists.

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

class CallBySelf
{
    public static function foo()
    {
        echo 'Foo', PHP_EOL;
    }
    
    public static function testCall()
    {
        $method = ['self', 'foo'];
        var_dump(is_callable($method));
        
        echo 'Call via call_user_func: ';
        call_user_func($method);
        
        echo 'Direct call: ';
        $method();
    }
}

CallBySelf::testCall();

Expected result:
----------------
Call via call_user_func: Foo
Direct call: Foo


Actual result:
--------------
bool(true)
Call via call_user_func: Foo
Direct call: 
Fatal error: Class 'self' not found in /in/Ssgep on line 19



------------------------------------------------------------------------



--
Edit this bug report at https://bugs.php.net/bug.php?id=76028&edit=1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.