Conozco la pregunta original sobre PHP 4.3, pero ahora es unos años más tarde y solo quería abogar por mi forma preferida de hacerlo en PHP 5.3 o superior.
PHP 5.3+ ahora incluye soporte para anonymous functions (closures), por lo que puede utilizar algunas técnicas de programación funcional estándar, como en lenguajes como JavaScript y Ruby (con algunas advertencias). Reescribir el ejemplo anterior call_user_func en "estilo de cierre" se vería así, que me parece más elegante:
$barber = function($type) {
echo "You wanted a $type haircut, no problem\n";
};
$barber('mushroom');
$barber('shave');
Obviamente, esto no significa que comprar mucho en este ejemplo - la potencia y flexibilidad viene cuando se pasa éstos funciones anónimas a otras funciones (como en la pregunta original). Así que usted puede hacer algo como:
$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";
Esto podría hacerse con call_user_func, por supuesto, pero me parece que esta sintaxis mucho más clara, especialmente una vez que los espacios de nombres y variables miembro se involucran.
Una advertencia: seré el primero en admitir que no sé exactamente qué está pasando aquí, pero no siempre se puede llamar a un cierre contenido en un miembro o variable estática, y posiblemente en algunos otros casos. Pero reasignarlo a una variable local permitirá que se invoque. Así, por ejemplo, esto le dará un error:
$some_value = \SomeNamespace\SomeClass::$closure($arg1, $arg2);
Pero esta sencilla solución corrige el problema:
$the_closure = \SomeNamespace\SomeClass::$closure;
$some_value = $the_closure($arg1, $arg2);
Esto suena como currying. –