Я только начинаю с PHP, и мне интересно, есть ли способ добавить анонимную функцию к экземпляру класса.
Например, скажем …
class A{ public B; } $c = new A(); //This is where I am getting a little confused... //The following wont work $c->B = function(){echo('HelloWorld');}; $c->B();
Я надеюсь, что это повторное использование кода в большом количестве различных приложений и сделать так, чтобы я мог просто «свопировать» и заменять функции в определенных случаях.
Я использую php5.3 (поэтому анонимные функции должны работать, а не так, как я их использую).
Большое спасибо за ваше время!
-GK
Вы можете использовать магическую функцию __call для этого задания. Не красота, но она работает.
как это:
class A { public $B; public function __call($closure, $args) { call_user_func_array($this->$closure, $args); } } $c = new A(); $c->B = function () { echo('HelloWorld'); }; $c->B();
# real ugly, but PoC... class a { function __call($f, $x) { call_user_func_array($this->$f, $x); } } $a = new a; $a->b = function() { echo "Hello world"; }; $a->b();
FWIW:
Работа с PHP 5.3 анонимными функциями интересна. Это не сработает:
$c->B = function() { echo func_get_arg(0); }; $c->B("This fails :(");
Это будет работать:
$c->B = function() { echo func_get_arg(0); }; $hilarious = $c->B; $hilarious("This works!");
Чтобы обойти это, вам нужно использовать __call
hack, как тот, который был предоставлен Oden .
Такое поведение может измениться в будущем. Развернутый массив RFC недавно был привязан к хомулу PHP , и в патче началось обсуждение цепочки функций , синтаксис которой может позволить, что вы пытаетесь обойтись без взлома __call. К сожалению, в прошлом оказалось трудным добиться функционального вызова цепочки функций.
Похоже, вы описываете шаблон стратегии или декораторский паттерн – есть другие способы добиться этого таким образом, с которым легче общаться с другими разработчиками, которые читают ваш код.
Вы можете сделать что-то в этом направлении (что также будет работать с обратными вызовами, которые не являются закрытием):
<?php class A { private $fun; function setFun($fun) { if (!is_callable($fun)) throw new InvalidArgumentException(); $this->fun = $fun; } public function fun() { call_user_func_array($this->fun, func_get_args()); } } $c = new A(); $c->setFun(function($a) { echo('HelloWorld ' . $a);}); $c->fun("here");
который дает HelloWorld here
.
Тем не менее, вы должны также рассмотреть наследование или шаблон декоратора .
Это больше не проблема PHP 7;
// no error $result = ($this->anonFunc)(); $result = ($this->anonFunc)($arg1, $arg2, ...);
Узнайте больше об АСТ .
Вместо того, чтобы подключать метод магии __call в свой класс, вы можете вместо этого выполнить вызываемый call_user_func
с помощью call_user_func
.
class A { public $b; } $c = new A(); $c->b = function(){echo('HelloWorld');}; call_user_func($c->b); // HelloWorld
Очевидно, было бы неплохо, если бы PHP предоставил некоторый синтаксис для выполнения этого напрямую.