Я пытаюсь запустить свойство функции $ greeter экземпляра $ greeter класса Greeter. Я прочитал ответы из этого поста но не смог заставить их работать (пост также упоминает _call, traits, stdClass, возвращая функцию из функции (что не имеет смысла, почему это работает без необходимости дважды вызывать), и данные решения кажутся излишними за простую вещь, которую я пытаюсь достичь). Возможно, мой случай немного отличается. Я не понимаю, почему парсер портит.
class Greeter {
private $greeter;
function __construct() {
$this->greeter = function() {
echo "Hello!\n";
};
}
public function greet() {
$this->greeter();
}
}
// THIS WORKS AS EXPECTED:
$hello = function() { echo "Hi!\n"; };
$hello();
$greeter = new Greeter();
// NEITHER OF THESE WORK:
call_user_func($greeter->greet);
$greeter->greet();
$greeter['greet']();
ВЫХОД:
Hi!
<br />
<b>Warning</b>: call_user_func() expects parameter 1 to be a valid callback, no array or string given on line <b>30</b><br />
<br />
<b>Fatal error</b>: Call to undefined method Greeter::greeter() on line <b>15</b><br />
ОК, это работает, но зачем мне использовать call_user_func
совсем? Это проблема с грамматикой PHP, что по какой-то причине у парсера возникают проблемы? C ++ раньше имел проблемы с разбором <<
используется с вложенными std::map
с, и в то время нужно было написать < <
чтобы избежать проблемы. Затем была введена хитрость в грамматике, чтобы решить проблему. Я не понимаю, почему то же самое не может произойти в грамматике PHP, чтобы сделать call_user_func
ненужным.
class Greeter {
private $greeter;
function __construct() {
$this->greeter = function() {
echo "Hello!\n";
};
}
public function greet() {
call_user_func($this->greeter);
}
}
// THIS WORKS AS EXPECTED:
$hello = function() { echo "Hi!\n"; };
$hello();
$greeter = new Greeter();
// NOW THIS ALSO WORKS AS EXPECTED:
$greeter->greet();
Добро пожаловать в забавный PHP.
<?php
class A {
public function f() {
echo 'hi';
}
}
$a = new A();
$a->f(); // yes
call_user_func($a->f); // no $a->f is not a func pointer in PHP
call_user_func([$a, 'f']); // yes [$obj, $method_string] is callable
$c = [$a, 'f'];
$c(); // yes it's a callable
[$a, 'f'](); // no PHP don't like that
$c = function() use($a) { $a->f(); };
$c(); // yes
function() use($a) { $a->f(); }(); // no
(function() use($a) { $a->f(); })(); // no
// edit: there is more fun I forgot
$m = 'f';
$a->$m(); // yes
$a->{'greet'}(); // yes
Что ж, иногда нелегко понять, что делает PHP, но есть много случаев, которые вы не можете написать в одном выражении.
То же самое для empty($this->getNumber())
или в старой версии с разыменованием массива $this->getArray()[4]
,
Кстати, вы имели в виду закрытие >>
против > >
в шаблонах C ++, которые были проанализированы как операторы bithift, но теперь все в порядке с C ++ 11.