PHP5.3: “Назовите к неопределенному методу” ошибку, когда вызов вызывает от переменной класса

Я делал, некоторые тесты (для замены старого кода) __ вызывают волшебный метод, и я не уверен, что это - ошибка или нет:

Позволяет предполагают, что у нас есть класс:

class Calc {
    function __invoke($a,$b){
        return $a*$b;
    }
}

Следующее возможно и работает без любой проблемы:

$c = new Calc;
$k = $c;
echo $k(4,5); //outputs 20

Однако, если я хочу иметь другой класс для хранения экземпляра того объекта, это не работает:

class Test {
    public $k;
    function __construct() {
        $c = new Calc;
        $this->k = $c; //Just to show a similar situation than before
        // $this-k = new Calc; produces the same error.
    }
}

Ошибка происходит, когда мы пытаемся назвать ее как:

$t = new Test;
echo $t->k(4,5); //Error: Call to undefined method Test::k()

Я знаю, что "решение" могло состоять в том, чтобы иметь функцию в классе Тест (названный k) для "переведения" вызова с помощью call_user_func_array, но это не изящно.

Я должен сохранить тот экземпляр в общем классе (в целях дизайна) и смочь назвать его как функцию от других классов... какое-либо предложение?

Обновление:

Я нашел что-то интересным (по крайней мере, в моих целях):

Если мы присваиваем "переменную класса" в локальную переменную, она работает:

$t = new Test;
$m = $t->k;
echo $m(4,5);
6
задан lepe 24 June 2010 в 07:56
поделиться

3 ответа

Когда вы выполняете $ test-> k () , PHP думает, что вы вызываете метод в экземпляре $ test . Поскольку не существует метода с именем k () , PHP выдает исключение. Что вы пытаетесь сделать, так это заставить PHP вернуть общедоступное свойство k и вызвать его, но для этого вы должны сначала присвоить k переменной. Это вопрос разыменования.

Вы можете добавить волшебный метод __ call в свой класс Test , чтобы проверить, существует ли свойство с именем вызываемого метода, и вызвать его вместо этого:

public function __call($method, $args) {
    if(property_exists($this, $method)) {
        $prop = $this->$method;
        return $prop();
    }
}

Я оставляю добавление аргументы для обращения к вам. Вы также можете проверить, является ли свойство is_callable .

Но в любом случае вы можете сделать

$test->k();
5
ответ дан 8 December 2019 в 18:32
поделиться

PHP думает, что вы хотите вызвать метод k на экземпляре $t, когда вы это делаете:

$t->k(4, 5)

что вполне разумно. Вы можете использовать промежуточную переменную для вызова объекта:

$b = $t->k;
$b(4, 5);

См. также ошибка #50029, в которой описана ваша проблема.

6
ответ дан 8 December 2019 в 18:32
поделиться

Вы не можете использовать синтаксис метода (например, $ foo-> bar ()) для вызова замыканий или объектов с __invoke, поскольку движок всегда думает, что это вызов метода. Вы можете смоделировать это с помощью __call:

function __call($name, $params) {
  if(is_callable($this->$name)) {
    call_user_func_array($this->$name, $params);
  }
}

, но он не будет работать как есть.

2
ответ дан 8 December 2019 в 18:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: