лямбда — обратный вызов PHP — как выполнить его в классе?

Я пытаюсь понять популярное использование PHP закрытия / обратного вызова функций в маршрутизации запросов в современных рамках. Slim, например, позволяет делать следующее:

$app->get('/hello/:name', function ($name) {
echo "Hello, $name";
});
$app->run();

Мой эксперимент:

class Foo
{
private $string;
private $callback;

public function get($string, $callback)
{
$this->string = $string;
$this->callback = $callback;
}

public function run()
{
return $this->get($this->string, $this->callback);
}
}

$Foo = new Foo;
$Foo->get('/world', function($name) {
return "Hello " . $name;
});

$Foo->run();

Как можно выполнить Перезвоните в классе, так что вернуть Hello World?

0

Решение

При разработке фреймворков это немного сложнее, чтобы добиться большей гибкости.
Но в этом простом случае вы можете просто использовать call_user_func_array () или же call_user_func (). Я рекомендую использовать call_user_func_array () потому что легче передавать много аргументов:

class Foo
{
private $string;
private $callback;

public function get($string, callable $callback)
{
$this->string = $string;
$this->callback = $callback;
}

public function run()
{
return call_user_func_array($this->callback, [$this->string]);
# OR
# return call_user_func($this->callback, $this->string);
# OR
#$fn = $this->callback; return $fn($this->string);

}
}

$Foo = new Foo;
$Foo->get('/world', function($name) {
return "Hello " . $name;
});

print $Foo->run();
1

Другие решения

На основе вашего примера кода это должно быть так:

    public function get($string, $callback)
{
//assign input parameter to object's propety
$this->string = $string;
$this->callback = $callback;

}

public function run()
{
/* if you want to avoid using this variable
use call_user_func */
$callback = $this->callback;

// run the callback
return $callback($this->string);
}
}

$Foo = new Foo;
$Foo->get('world', function($name) {
return "Hello " . $name;
});

$return = $Foo->run();
var_dump($return); //this will return 'Hello world'
1

По вопросам рекламы [email protected]