2009-10-20 9 views
70

Je suis sûr qu'il y a une explication très facile pour cela. Quelle est la différence entre ceci:PHP call_user_func vs simplement appeler la fonction

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

... et cela (et quels sont les avantages?):

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

Répondre

65

Utilisez toujours le nom de la fonction réelle lorsque vous le connaissez.

call_user_func est d'appeler des fonctions dont vous ne connaissez pas le nom à l'avance mais il est beaucoup moins efficace puisque le programme doit rechercher la fonction au moment de l'exécution.

+0

Merci Kai. call_user_func s'est avéré être exactement ce dont j'avais besoin. – jay

+38

'call_user_func' n'est pas forcément nécessaire. Vous pouvez toujours appeler une fonction en utilisant des fonctions variables: '$ some_func()'. 'call_user_func_array' est celui qui est vraiment utile. –

+18

php a toujours besoin de "rechercher la fonction à l'exécution" – VolkerK

0

dans votre premier exemple que vous utilisez le nom de la fonction qui est une chaîne. cela pourrait venir de l'extérieur ou être déterminé à la volée. c'est-à-dire que vous ne savez pas quelle fonction devra être exécutée au moment de la création du code.

12

l'option call_user_func est là pour que vous puissiez faire des choses comme:

$dynamicFunctionName = "barber"; 

call_user_func($dynamicFunctionName, 'mushroom'); 

où la chaîne dynamicFunctionName pourrait être plus excitant et généré lors de l'exécution. Vous ne devriez pas utiliser call_user_func à moins d'y être obligé, car c'est plus lent.

+0

Il semble que vous pourriez utiliser une fonction variable dans ce scénario. –

5

J'imagine qu'il est utile pour appeler une fonction que vous ne connaissez pas le nom de l'avance ... Quelque chose comme:

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

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

Non. Nous pouvons toujours faire '$ func ('stuff');' – dotslash

+0

Oui, mais la différence utilise une variable produira une erreur PHP Fatal contre un avertissement PHP si call_user_func est utilisé. –

+0

Cela n'a pas annulé la valeur des fonctions de variable sur 'call_user_func()' dans ce scénario. –

28

Bien que vous pouvez appeler les noms de fonctions variables ainsi:

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

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

Il y a des cas où vous ne savez pas combien d'arguments vous passez. Considérez ce qui suit:

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

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

Il est également à portée de main pour appeler des méthodes statiques et objet respectivement:

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

Je sais que c'est vieux, mais n'a pas pu trouver d'articles ailleurs. Est-il plus avantageux d'utiliser call_user_func ('customFunction') comme étant associé à $ variableFunction()? Quelles sont les différences? Merci! –

-1

Lors de l'utilisation des espaces de noms, call_user_func() est la seule façon d'exécuter une fonction que vous ne connaissez pas le nom de l'avance, par exemple:

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

Si toutes vos fonctions étaient dans le même espace, alors il ne serait pas une telle question, que vous pouvez utiliser quelque chose comme ceci:

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

Edit: Après @Jannis disant que je me trompe, je l'ai fait un peu plus de tests, et n'a pas été beaucoup de chance:

<?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()' 
} 

Vous pouvez voir les résultats de sortie ici: https://3v4l.org/iBERh il semble que la seconde méthode fonctionne pour PHP 7 et plus, mais pas PHP 5.6.

+0

. pour ne pas être vrai. $ fn = '\ Foo \ Bar \ getCurrency'; $ fn(); –

+0

Salut @Jannis, je ne trouve pas que c'est vrai, peut-être que vous pouvez voir où je vais mal, j'ai ajouté un exemple plus détaillé à ma réponse. – ThomasRedstone

+0

@ThomasRedstone avez-vous eu besoin de ces fonctions auparavant? php ne charge pas automatiquement les fonctions d'autres fichiers. Aussi ce qui est avec ce petit vs grosses lettres dans les espaces de noms. Est-ce que Bar est une classe? alors c'est une autre utilisation. –

1

Il n'y a aucun avantage à appeler la fonction comme ça parce que je pense qu'il appelait principalement la fonction "user" (comme le plugin) parce que l'édition du fichier core n'est pas une bonne option. voici un exemple sale utilisé par 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 
?> 

sortie

hello world my name is Tasikmalaya 
0

Avec PHP 7, vous pouvez utiliser la syntaxe plus belle-fonction variable partout. Il fonctionne avec les fonctions static/instance, et il peut prendre un tableau de paramètres. Plus d'infos sur https://trowski.com/2015/06/20/php-callable-paradox

$ret = $callable(...$params); 
Questions connexes