开发者

PHP Callable Object as Object Member

开发者 https://www.devze.com 2022-12-10 03:16 出处:网络
I have a class Logger which, among other things has a method Log. As Log is the most common use of the Logger instance, I have wired __invoke to call Log

I have a class Logger which, among other things has a method Log.

As Log is the most common use of the Logger instance, I have wired __invoke to call Log

Another class, "Site" contains a member "Log", an instance of Logger.

Why would this work:

$L开发者_JAVA百科og = $this->Log;  
$Log("Message");  

But not this:

$this->Log("Message");

The former fails with "PHP Fatal error: Call to undefined method Site::Log()"

Is this a limitation of the callable object implementation, or am I misunderstanding something?


Unfortunately, this is (still) a limitation of PHP, but it makes sense when you think about it, as a class can contain properties and methods that share names. For example:

<?php
class Test {
    public $log;

    public function __construct() {
        $this->log = function() {
            echo 'In Test::log property';
        };
    }

    public function log() {
        echo 'In Test::log() method';
    }
}

$test = new Test;
$test->log(); // In Test::log() method
call_user_func($test->log); // In Test::log property
?>

If PHP were to allow the syntax you desire, which function would be invoked? Unfortunately, that only leaves us with call_user_func[_array]() (or copying $this->log to another variable and invoking that).

However, it would be nice if the following syntax was acceptable:

<?php
{$test->log}();
?>

But alas, it is not.


Same reasons you can't do this:

$value = $this->getArray()["key"];

or even this

$value = getArray()["key"];

Because PHP syntax doesn't do short hand very well.


This may work:

${this->Log}("Message");

But perhaps it's just easier and better to use the full call? There doesn't seem to be a way to get what you want to work on the one line.

The error in your question indicates it is looking for a function defined on the class which doesn't exist. An invokable object isn't a function, and it seems it can't be treated as one in this case.


as of php7.4 the following code works for me

($this->Log)("Message");
0

精彩评论

暂无评论...
验证码 换一张
取 消