332 votes

Comment appeler une fonction à partir d'une chaîne de caractères stockée dans une variable ?

J'ai besoin de pouvoir appeler une fonction, mais le nom de la fonction est stocké dans une variable, est-ce possible ? par exemple

function foo ()
{
    //code here
}

function bar ()
{
    //code here
}

$functionName = "foo";
// I need to call the function based on what is $functionName

518voto

knittl Points 64110

98 votes

Si vous devez appeler la fonction d'un objet dont le nom se trouve dans une variable, faites ceci : call_user_func( array($obj,$func), $params )

1 votes

Voir aussi ma réponse ci-dessous si vous avez affaire à des classes et des méthodes. Je ne m'attendais pas à ce que j'ai trouvé.

0 votes

Comment puis-je annuler l'erreur de définition de fonction si la fonction n'a pas été définie ? Est-ce que if($functionName) suffit ?

149voto

Mészáros Lajos Points 620

Ma version préférée est la version en ligne :

${"variableName"} = 12;

$className->{"propertyName"};
$className->{"methodName"}();

StaticClass::${"propertyName"};
StaticClass::{"methodName"}();

Vous pouvez également placer des variables ou des expressions à l'intérieur des parenthèses !

1 votes

@marcioAlmada : postez un commentaire au lieu de modifier les réponses des autres de cette manière ; cela ajoute de la confusion - on ne sait pas qui a dit quoi. [pour les curieux : voir les révisions pour les explications].

5 votes

Ok @kryger. Ligne 2 {"functionName"}(); n'est pas légal et entraînera une erreur de syntaxe.

4 votes

Merci pour les réponses, il y a effectivement une erreur, même en php 5.4, donc cette syntaxe ne fonctionne qu'avec les méthodes objet. J'ai modifié le message.

24voto

Sev Points 6532

Oui, c'est possible :

function foo($msg) {
    echo $msg."<br />";
}
$var1 = "foo";
$var1("testing 1,2,3");

Fuente: http://www.onlamp.com/pub/a/php/2001/05/17/php_foundations.html?page=2

13voto

Chris K Points 3940

Au cas où quelqu'un d'autre serait amené ici par Google parce qu'il essayait d'utiliser une variable pour une méthode dans une classe, voici un exemple de code qui fonctionnera réellement. Aucune des solutions ci-dessus n'a fonctionné dans mon cas. La différence essentielle est le & dans la déclaration de $c = & new... y &$c qui passe dans call_user_func .

Mon cas spécifique est l'implémentation du code de quelqu'un qui a à faire avec des couleurs et deux méthodes membres. lighten() y darken() de la classe csscolor.php. Pour une raison quelconque, je voulais que le même code soit capable d'appeler l'éclaircissement ou l'assombrissement plutôt que de le sélectionner avec de la logique. C'est peut-être le résultat de mon entêtement à ne pas utiliser simplement if-else ou à modifier le code qui appelle cette méthode.

$lightdark="lighten"; // or optionally can be darken
$color="fcc";   // a hex color
$percent=0.15;  
include_once("csscolor.php");
$c = & new CSS_Color($color);
$rtn=call_user_func( array(&$c,$lightdark),$color,$percent);

Notez que si vous essayez quoi que ce soit avec $c->{...} n'a pas fonctionné. En parcourant le contenu des contributions des lecteurs en bas de la page de php.net sur call_user_func j'ai pu rassembler les éléments ci-dessus. Aussi, notez que $params comme un tableau n'a pas fonctionné pour moi :

// This doesn't work:
$params=Array($color,$percent);
$rtn=call_user_func( array(&$c,$lightdark),$params);

La tentative ci-dessus donnerait un avertissement sur la méthode qui attend un deuxième argument (pourcentage).

0 votes

Que fait "$c = & new CSS_Color" ? Je parle de l'ampoule (&). Que change ce & ?

0 votes

@danon & est "adresse de" ou l'opérateur "référence". Je suis en train d'instiller un nouvel objet de la classe CSS_Color et d'assigner sa référence (aka adresse) à $c. Je déteste répéter du code, c'est pourquoi j'utilise souvent des noms de variables.

1 votes

Je ne comprends pas. Les objets ne sont-ils pas passés par référence partout de toute façon ? Je veux dire, si vous passez un $c à une fonction et que vous le modifiez, l'objet original sera également affecté, n'est-ce pas ? Peu importe que vous ayez utilisé ce & ou non, ai-je raison ?

10voto

karim79 Points 178055

Par souci d'exhaustivité, vous pouvez également utiliser eval() :

$functionName = "foo()";
eval($functionName);

Cependant, call_user_func() est le bon moyen.

8 votes

Il faut noter que eval() permettra le même comportement mais il permettra aussi d'exécuter n'importe quel code PHP. La variable pourrait donc être utilisée pour détourner le système. Le call_user_func() n'apporte pas de tels problèmes de sécurité.

4 votes

eval n'est pas une solution à cette question.

2 votes

Ne faites pas cela, car un attaquant pourrait anéantir entièrement votre serveur.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X