2009-03-09 13 views
41

Necesito pasar una función como parámetro a otra función y luego llamar a la función pasada desde dentro de la función ... Esto es probablemente más fácil de explicar en código ... Básicamente quiero hacer algo como esto:PHP pass function como param entonces llame a la función?

function ($functionToBeCalled) 
{ 
    call($functionToBeCalled,additional_params); 
} 

¿hay una manera de hacer eso .. estoy usando PHP 4.3.9

Gracias!

+0

Esto suena como currying. –

Respuesta

77

Creo que está buscando call_user_func.

Un ejemplo del Manual de PHP:

<?php 
function barber($type) { 
    echo "You wanted a $type haircut, no problem"; 
} 
call_user_func('barber', "mushroom"); 
call_user_func('barber', "shave"); 
?> 
+48

Regla de cortes de champiñón! – Alex

+5

y entonces, ¿qué sucede cuando el barbero pertenece a una clase diferente? espacio de nombres diferente? – abbood

25
function foo($function) { 
    $function(" World"); 
} 
function bar($params) { 
    echo "Hello".$params; 
} 

$variable = 'bar'; 
foo($variable); 

Además, puede hacerlo de esta manera. Ver variable functions.

+2

Creo que estás saltando un poco el arma allí. IIRC, ese código no comenzará a funcionar hasta que salga PHP 5.3. –

+1

"barra" tiene que ser citado, ya que es una cadena. – Gumbo

+1

@Jeremy DeGroot funciones variables han existido por siempre – Greg

22

En php esto es muy simple.

<?php 

function here() { 
    print 'here'; 
} 


function dynamo($name) { 
$name(); 
} 

//Will work 
dynamo('here'); 
//Will fail 
dynamo('not_here'); 
10

También podría usar call_user_func_array(). Le permite pasar una matriz de parámetros como el segundo parámetro para que no tenga que saber exactamente cuántas variables está pasando.

7

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); 
4

Si necesita función de paso con el parámetro por parámetro, puede intentar esto:

function foo ($param1){ 
    return $param1; 
} 

function bar ($foo_function, $foo_param){ 
    echo $foo_function($foo_param); 
} 

//call function bar 
bar('foo', 'Hi there'); //this will print: 'Hi there' 

phpfiddle example

espero que sea útil ...

+0

¿Esto realmente funciona? ¿Alguna referencia? –

+0

Sí, esto funcionará ... Lo hice yo mismo, sin referencia ... –

+0

¿Alguien puede confirmarlo? –

Cuestiones relacionadas