retornan - Aceptar la función como parámetro en PHP
manejo de funciones en php (8)
Ejemplo simple usando una clase:
class test {
public function works($other_parameter, $function_as_parameter)
{
return $function_as_parameter($other_parameter) ;
}
}
$obj = new test() ;
echo $obj->works(''working well'',function($other_parameter){
return $other_parameter;
});
Me he estado preguntando si es posible o no pasar una función como parámetro en PHP; Quiero algo así como cuando estás programando en JS:
object.exampleMethod(function(){
// some stuff to execute
});
Lo que quiero es ejecutar esa función en algún lugar en exampleMethod. ¿Es eso posible en PHP?
Es posible si usa PHP 5.3.0 o superior.
Ver Funciones Anónimas en el manual.
En tu caso, definirías exampleMethod
así:
function exampleMethod($anonFunc) {
//execute anonymous function
$anonFunc();
}
Probado para PHP 5.3
Como veo aquí, la función anónima podría ayudarte: http://php.net/manual/en/functions.anonymous.php
Lo que probablemente necesitará y no se dice antes es cómo pasar una función sin envolverla dentro de una función creada sobre la marcha . Como verá más adelante, deberá pasar el nombre de la función escrito en una cadena como parámetro, verificar su "capacidad de invocación" y luego llamarlo.
La función de hacer cheque:
if( is_callable( $string_function_name ) ){
/*perform the call*/
}
Luego, para llamarlo, use este fragmento de código (si también necesita parámetros, colóquelos en una matriz), visto en: http://php.net/manual/en/function.call-user-func.php
call_user_func_array( "string_holding_the_name_of_your_function", $arrayOfParameters );
como sigue (de forma similar, sin parámetros):
function funToBeCalled(){
print("----------------------i''m here");
}
function wrapCaller($fun){
if( is_callable($fun)){
print("called");
call_user_func($fun);
}else{
print($fun." not called");
}
}
wrapCaller("funToBeCalled");
wrapCaller("cannot call me");
Aquí hay una clase que explica cómo hacer algo similar:
<?php
class HolderValuesOrFunctionsAsString{
private $functions = array();
private $vars = array();
function __set($name,$data){
if(is_callable($data))
$this->functions[$name] = $data;
else
$this->vars[$name] = $data;
}
function __get($name){
$t = $this->vars[$name];
if(isset($t))
return $t;
else{
$t = $this->$functions[$name];
if( isset($t))
return $t;
}
}
function __call($method,$args=null){
$fun = $this->functions[$method];
if(isset($fun)){
call_user_func_array($fun,$args);
} else {
// error out
print("ERROR: Funciton not found: ". $method);
}
}
}
?>
y un ejemplo de uso
<?php
/*create a sample function*/
function sayHello($some = "all"){
?>
<br>hello to <?=$some?><br>
<?php
}
$obj = new HolderValuesOrFunctionsAsString;
/*do the assignement*/
$obj->justPrintSomething = ''sayHello''; /*note that the given
"sayHello" it''s a string ! */
/*now call it*/
$obj->justPrintSomething(); /*will print: "hello to all" and
a break-line, for html purpose*/
/*if the string assigned is not denoting a defined method
, it''s treat as a simple value*/
$obj->justPrintSomething = ''thisFunctionJustNotExistsLOL'';
echo $obj->justPrintSomething; /*what do you expect to print?
just that string*/
/*N.B.: "justPrintSomething" is treated as a variable now!
as the __set ''s override specify"*/
/*after the assignement, the what is the function''s destiny assigned before ? It still works, because it''s held on a different array*/
$obj->justPrintSomething("Jack Sparrow");
/*You can use that "variable", ie "justPrintSomething", in both ways !! so you can call "justPrintSomething" passing itself as a parameter*/
$obj->justPrintSomething( $obj->justPrintSomething );
/*prints: "hello to thisFunctionJustNotExistsLOL" and a break-line*/
/*in fact, "justPrintSomething" it''s a name used to identify both
a value (into the dictionary of values) or a function-name
(into the dictionary of functions)*/
?>
Según la respuesta de @Zombat, es mejor validar primero las Funciones anónimas:
function exampleMethod($anonFunc) {
//execute anonymous function
if (is_callable($anonFunc)) {
$anonFunc();
}
}
O valide el tipo de argumento desde PHP 5.4.0:
function exampleMethod(callable $anonFunc) {}
Simplemente codifícalo así:
function example($anon) {
$anon();
}
example(function(){
// some codes here
});
sería genial si pudieras inventar algo como esto (inspirado en Laravel Illuminate):
Object::method("param_1", function($param){
$param->something();
});
Solo para agregar a los demás, puede pasar un nombre de función:
function someFunc($a)
{
echo $a;
}
function callFunc($name)
{
$name(''funky!'');
}
callFunc(''someFunc'');
Esto funcionará en PHP4.
También puede usar create_function para crear una función como variable y pasarla. Sin embargo, me gusta más la sensación de funciones anónimas . Ve a zombi
VERSIÓN PHP> = 5.3.0
Ejemplo 1: básico
function test($test_param, $my_function) {
return $my_function($test_param);
}
test("param", function($param) {
echo $param;
}); //will echo "param"
Ejemplo 2: objeto estándar
$obj = new stdClass();
$obj->test = function ($test_param, $my_function) {
return $my_function($test_param);
};
$test = $obj->test;
$test("param", function($param) {
echo $param;
});
Ejemplo 3: llamada de clase no estática
class obj{
public function test($test_param, $my_function) {
return $my_function($test_param);
}
}
$obj = new obj();
$obj->test("param", function($param) {
echo $param;
});
Ejemplo 4: llamada de clase estática
class obj {
public static function test($test_param, $my_function) {
return $my_function($test_param);
}
}
obj::test("param", function($param) {
echo $param;
});