2009-10-20 6 views
70

Estoy seguro de que hay una explicación muy fácil para esto. ¿Cuál es la diferencia entre esto:PHP call_user_func versus función de llamada

function barber($type){ 
    echo "You wanted a $type haircut, no problem\n"; 
} 
call_user_func('barber', "mushroom"); 
call_user_func('barber', "shave"); 

... y esto (y cuáles son los beneficios?):

function barber($type){ 
    echo "You wanted a $type haircut, no problem\n"; 
} 
barber('mushroom'); 
barber('shave'); 

Respuesta

65

Utilice siempre el nombre de la función real cuando lo conozca.

call_user_func es para funciones de llamada cuyo nombre no conoce de antemano, pero es mucho menos eficiente ya que el programa tiene que buscar la función en tiempo de ejecución.

+0

Gracias Kai. call_user_func resultó ser exactamente lo que necesitaba. – jay

+38

'call_user_func' no es necesariamente necesario. Siempre puede llamar a una función mediante el uso de funciones de variables: '$ some_func()'. 'call_user_func_array' es el que es realmente útil. –

+18

php siempre necesita "buscar la función en tiempo de ejecución" – VolkerK

0

en su primer ejemplo está utilizando una función que es una cadena. podría venir del exterior o determinarse sobre la marcha. es decir, no sabe qué función deberá ejecutarse en el momento de la creación del código.

12

la opción call_user_func está ahí para que pueda hacer cosas como:

$dynamicFunctionName = "barber"; 

call_user_func($dynamicFunctionName, 'mushroom'); 

donde la cadena dynamicFunctionName podría ser más emocionante y generada en tiempo de ejecución. No debe usar call_user_func a menos que sea necesario, porque es más lento.

+0

Parece que podría usar una función variable en este escenario. –

5

Me imagino que es útil para llamar a una función que no conoce el nombre de antelación ... Algo así como:

switch($value): 
{ 
    case 7: 
    $func = 'run'; 
    break; 
    default: 
    $func = 'stop'; 
    break; 
} 

call_user_func($func, 'stuff'); 
+3

No. Todavía podemos hacer '$ func ('cosas');' – dotslash

+0

Sí, pero la diferencia está usando una variable producirá un error de PHP Fatal contra una advertencia de PHP si se usa call_user_func. –

+0

Esto no ha negado el valor de las funciones variables sobre 'call_user_func()' en este escenario. –

28

Aunque se puede llamar a los nombres de funciones variables de esta manera:

function printIt($str) { print($str); } 

$funcname = 'printIt'; 
$funcname('Hello world!'); 

hay casos en los que no sabe cuántos argumentos está pasando. Considere lo siguiente:

function someFunc() { 
    $args = func_get_args(); 
    // do something 
} 

call_user_func_array('someFunc',array('one','two','three')); 

También es útil para llamar a métodos estáticos y objetos, respectivamente:

call_user_func(array('someClass','someFunc'),$arg); 
call_user_func(array($myObj,'someFunc'),$arg); 
+6

Sé que esto es antiguo, pero no pude encontrar artículos en otros lugares. ¿Es más ventajoso usar call_user_func ('customFunction') como apposed a $ variableFunction()? ¿Cuáles son las diferencias? ¡Gracias! –

-1

Al utilizar espacios de nombres, call_user_func() es la única forma de ejecutar una función que no sabes el nombre de antemano, por ejemplo:

$function = '\Utilities\SearchTools::getCurrency'; 
call_user_func($function,'USA'); 

Si todos sus funciones estaban en el mismo espacio de nombres, entonces no sería un problema tal, que se podría utilizar algo como esto:

$function = 'getCurrency'; 
$function('USA'); 

Editar: Siguiendo @Jannis diciendo que estoy equivocado Hice un poco más pruebas, y no estaba teniendo mucha suerte:

<?php 
namespace Foo { 

    class Bar { 
     public static function getBar() { 
      return 'Bar'; 
     } 
    } 
    echo "<h1>Bar: ".\Foo\Bar::getBar()."</h1>"; 
    // outputs 'Bar: Bar' 
    $function = '\Foo\Bar::getBar'; 
    echo "<h1>Bar: ".$function()."</h1>"; 
    // outputs 'Fatal error: Call to undefined function \Foo\Bar::getBar()' 
    $function = '\Foo\Bar\getBar'; 
    echo "<h1>Bar: ".$function()."</h1>"; 
    // outputs 'Fatal error: Call to undefined function \foo\Bar\getBar()' 
} 

Se puede ver los resultados de salida aquí: https://3v4l.org/iBERh parece que el segundo método funciona para PHP 7 en adelante, pero no PHP 5.6.

+0

. por no ser cierto $ fn = '\ Foo \ Bar \ getCurrency'; $ fn(); –

+0

Hola @Jannis, no creo que eso sea cierto, tal vez puedas ver dónde me estoy equivocando, he agregado un ejemplo más detallado a mi respuesta. – ThomasRedstone

+0

@ThomasRedstone ¿requirió esas funciones de antemano? php no carga funciones automáticas desde otros archivos. Además, ¿qué pasa con las letras pequeñas vs grandes en espacios de nombres? ¿Bar es una clase? entonces ese es otro uso. –

1

No hay beneficios llamando a la función de esa manera porque creo que se utiliza principalmente para llamar a la función de "usuario" (como el complemento) porque la edición del archivo central no es una buena opción. aquí están sucios ejemplo utilizado por Wordpress

<?php 
/* 
* my_plugin.php 
*/ 

function myLocation($content){ 
    return str_replace('@', 'world', $content); 
} 

function myName($content){ 
    return $content."Tasikmalaya"; 
} 

add_filter('the_content', 'myLocation'); 
add_filter('the_content', 'myName'); 

?> 

...

<?php 
/* 
* core.php 
* read only 
*/ 

$content = "hello @ my name is "; 
$listFunc = array(); 

// store user function to array (in my_plugin.php) 
function add_filter($fName, $funct) 
{ 
    $listFunc[$fName]= $funct; 
} 

// execute list user defined function 
function apply_filter($funct, $content) 
{ 
    global $listFunc; 

    if(isset($listFunc)) 
    { 
    foreach($listFunc as $key => $value) 
    { 
     if($key == $funct) 
     { 
     $content = call_user_func($listFunc[$key], $content); 
     } 
    } 
    } 
    return $content; 
} 

function the_content() 
{ 
    $content = apply_filter('the_content', $content); 
    echo $content; 
} 

?> 

....

<?php 
require_once("core.php"); 
require_once("my_plugin.php"); 

the_content(); // hello world my name is Tasikmalaya 
?> 

salida

hello world my name is Tasikmalaya 
0

Con PHP 7 se puede utilizar la sintaxis de la función de la variable más agradable en todas partes. Funciona con funciones estáticas/de instancia, y puede tomar una matriz de parámetros. Más información en https://trowski.com/2015/06/20/php-callable-paradox

$ret = $callable(...$params); 
Cuestiones relacionadas