Gianluca Ghettini
Gianluca Ghettini

Reputation: 11628

I get this error "Function name must be a string"

I have a PHP class where one of the private member is a callback to my log function (i.e. in PHP land, a function pointer is simply a string containing the name of the function to call).

self::$logferr = "msgfunc";
self::$logferr($res);

I get this error:

Fatal error: Function name must be a string

self::$logferr is equal to "msgfunc" which is my log function.

If I rewrite the code like this (on the same very class method):

$tmp = "msgfunc";
$tmp($res);

It works, the log function get called

Upvotes: 1

Views: 1439

Answers (4)

lighter
lighter

Reputation: 2806

You can use call_user_func. ref: this

call_user_func(self::$logferr, $res);

Upvotes: 1

Mike Doe
Mike Doe

Reputation: 17566

Just wrap your variable in parenthesis, let PHP resolve the value first:

(self::$logferr)($res);

Proof of concept

Upvotes: 4

ThW
ThW

Reputation: 19492

Let's build a reproducible example:

class Foo {

    private static $_loggerCallback;

    static function setLogCallback(callable $loggerCallback) {
        self::$_loggerCallback = $loggerCallback;
    }

    static function log(...$arguments) {
        if (NULL !== self::$_loggerCallback) {
          return self::$_loggerCallback(...$arguments);
        }
        return NULL;
    }
}


Foo::setLogCallback(function() { echo 'success'; } );
Foo::log();

Output:

Notice: Undefined variable: _loggerCallback in /in/f3stL on line 13

Fatal error: Uncaught Error: Function name must be a string in /in/f3stL:13

The notice reports the actual mistake in this case. If you do not get something like it, you should check your error reporting configuration.

The notice shows that PHP looks for a local variable $_loggerCallback. It tries to execute $_loggerCallback(...$arguments). Here are different possibilities to make the call explicit.

Use parenthesis (PHP >= 7.0):

return (self::$_loggerCallback)(...$arguments);

Use a local variable (as you did):

$callback = self::$_loggerCallback;
return $callback(...$arguments);

A small advise. PHP support anonymous functions. You do not need a (global) function for a callback. This avoids calling to the function by name as well.

Upvotes: 0

Rakesh Jakhar
Rakesh Jakhar

Reputation: 6388

You should call it by using

 self::{self::$logferr}($req)

Working example : https://3v4l.org/CYURS

Upvotes: 1

Related Questions