Вызываемый объект PHP как член объекта - PullRequest
5 голосов
/ 01 ноября 2009

У меня есть класс Logger, в котором, помимо прочего, есть метод Log.
Поскольку Log является наиболее распространенным вариантом использования Logger, я набрал __invoke для вызова Log

Другой класс, «Site», содержит член «Log», экземпляр Logger.

Почему это работает:

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

Но не это:

$this->Log("Message");

Первая ошибка завершается с «Роковой ошибкой PHP: вызов неопределенного метода Site :: Log ()»
Это ограничение реализации вызываемого объекта или я что-то неправильно понимаю?

Ответы [ 3 ]

7 голосов
/ 25 мая 2012

К сожалению, это (все еще) ограничение PHP, но имеет смысл, когда вы думаете об этом, поскольку класс может содержать свойства и методы, которые совместно используют имена. Например:

<?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
?>

Если бы PHP разрешил нужный вам синтаксис, какая функция была бы вызвана? К сожалению, это оставляет нам только call_user_func[_array]() (или копирование $this->log в другую переменную и ее вызов).

Однако было бы неплохо, если бы следующий синтаксис был приемлемым:

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

Но, увы, это не так.

1 голос
/ 01 ноября 2009

Те же причины, по которым вы не можете сделать это:

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

или даже это

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

Поскольку синтаксис PHP не очень хорошо подходит для коротких рук.

1 голос
/ 01 ноября 2009

Это может работать:

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

Но, возможно, просто и лучше использовать полный вызов? Кажется, нет способа получить то, что вы хотите работать в одной строке.

Ошибка в вашем вопросе указывает на то, что он ищет функцию, определенную в классе, которая не существует. Вызываемый объект не является функцией, и, похоже, в данном случае он не может рассматриваться как объект.

...