Я знаю оригинальный вопрос, заданный по поводу PHP 4.3, но сейчас, спустя несколько лет, я просто хотел отстаивать свой предпочтительный способ сделать это в PHP 5.3 или выше.
PHP 5.3+ теперь включает поддержку анонимных функций (замыканий) , поэтому вы можете использовать некоторые стандартные функциональные методы программирования, как в таких языках, как JavaScript и Ruby (с несколькими оговорками). Переписав приведенный выше пример call_user_func в «стиль закрытия», я бы выглядел более элегантно:
$barber = function($type) {
echo "You wanted a $type haircut, no problem\n";
};
$barber('mushroom');
$barber('shave');
Очевидно, что в этом примере это мало что дает - мощь и гибкость появляются, когда вы передаете эти анонимные функции другим функциям (как в первоначальном вопросе). Таким образом, вы можете сделать что-то вроде:
$barber_cost = function($quantity) {
return $quantity * 15;
};
$candy_shop_cost = function($quantity) {
return $quantity * 4.50; // It's Moonstruck chocolate, ok?
};
function get_cost($cost_fn, $quantity) {
return $cost_fn($quantity);
}
echo '3 haircuts cost $' . get_cost($barber_cost, 3) . "\n";
echo '6 candies cost $' . get_cost($candy_shop_cost, 6) . "\n";
Конечно, это можно сделать с помощью call_user_func, но я нахожу этот синтаксис намного более понятным, особенно после включения пространств имен и переменных-членов.
Одно предостережение: я первым признаю, что не знаю точно, что здесь происходит, но вы не всегда можете вызвать замыкание, содержащееся в члене или статической переменной, и, возможно, в некоторых других случаях. Но переназначение его на локальную переменную позволит вызвать его. Так, например, это даст вам ошибку:
$some_value = \SomeNamespace\SomeClass::$closure($arg1, $arg2);
Но этот простой обходной путь устраняет проблему:
$the_closure = \SomeNamespace\SomeClass::$closure;
$some_value = $the_closure($arg1, $arg2);