Znam oryginalne pytanie na temat PHP 4.3, ale teraz jest kilka lat później i chciałem po prostu poprzeć mój ulubiony sposób na zrobienie tego w PHP 5.3 lub nowszym.
PHP 5.3+ zawiera teraz obsługę anonymous functions (closures), więc możesz używać standardowych technik programowania funkcjonalnego, jak w językach takich jak JavaScript i Ruby (z kilkoma zastrzeżeniami). Przepisanie call_user_func powyższy przykład w stylu „zamknięcia” wyglądałby następująco, co znajdę bardziej eleganckie:
$barber = function($type) {
echo "You wanted a $type haircut, no problem\n";
};
$barber('mushroom');
$barber('shave');
Oczywiście, to nie kupuje Ci dużo w tym przykładzie - moc i elastyczność przychodzi kiedy przechodzą one anonimowe funkcje do innych funkcji (jak w pytaniu oryginalnym). Więc można zrobić coś takiego:
$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";
Można to zrobić z call_user_func, oczywiście, ale uważam, że ta składnia znacznie jaśniejsze, zwłaszcza gdy nazw i zmienne składowe angażować.
Jedno zastrzeżenie: Będę pierwszym, który przyzna, że nie wiem dokładnie, co się tutaj dzieje, ale nie zawsze można nazwać zamknięciem zawartym w zmiennej członkowskiej lub statycznej, a być może w niektórych innych przypadkach. Ale ponowne przypisanie go do zmiennej lokalnej pozwoli na jej wywołanie. Tak więc, na przykład, to daje błąd:
$some_value = \SomeNamespace\SomeClass::$closure($arg1, $arg2);
Ale to proste obejście rozwiązuje problem:
$the_closure = \SomeNamespace\SomeClass::$closure;
$some_value = $the_closure($arg1, $arg2);
To brzmi jak przyrządzanie curry. –