web-dev-qa-db-fra.com

Comment appeler la fonction PHP à partir d'une chaîne stockée dans une variable

Je dois pouvoir appeler une fonction, mais le nom de la fonction est stocké dans une variable, est-ce possible? par exemple:

 function foo () 
 {
 // code ici 
} 
 
 barre de fonction () 
 { 
 // code ici 
} 
 
 $ functionName = "foo"; 
 // j’ai besoin d’appeler la fonction en fonction de $ nomfonction 

Toute aide est la bienvenue.

Merci!

268
Lizard
438
knittl

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 entre crochets!

102
Lajos Meszaros

Oui c'est possible:

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

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

17
Sev

Comme déjà mentionné, il existe plusieurs façons de procéder, la méthode la plus sûre étant probablement call_user_func() ou, si nécessaire, vous pouvez également suivre la route de $function_name(). Il est possible de passer des arguments en utilisant ces deux méthodes

$function_name = 'foobar';

$function_name(arg1, arg2);

call_user_func_array($function_name, array(arg1, arg2));

Si la fonction que vous appelez appartient à un objet, vous pouvez toujours utiliser l’une de ces options.

$object->$function_name(arg1, arg2);

call_user_func_array(array($object, $function_name), array(arg1, arg2));

Toutefois, si vous utilisez la méthode $function_name(), il peut être judicieux de vérifier l'existence de la fonction si le nom est dynamique.

if(method_exists($object, $function_name))
{
    $object->$function_name(arg1, arg2);
}
17
olliefinn

Quelques années de retard, mais c’est la meilleure manière à l’heure actuelle:

$x = (new ReflectionFunction("foo"))->getClosure();
$x();
12
Internal Server Error

Si quelqu'un est 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. Aucun de ce qui précède n'a fonctionné pour ma situation. La principale différence est le & dans la déclaration de $c = & new... et &$c passé dans call_user_func.

Mon cas spécifique concerne l’implémentation du code d’une personne liée à des couleurs et à deux méthodes membres lighten() et darken() de la classe csscolor.php. Pour une raison quelconque, je voulais que le même code puisse appeler éclaircir ou assombrir plutôt que de le sélectionner avec logique. Cela peut être le résultat de mon obstination à ne pas utiliser simplement if-else ou à changer le code appelant 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 qu'essayer quoi que ce soit avec $c->{...} n'a pas fonctionné. En parcourant le contenu fourni par le lecteur au bas de la page de php.net sur call_user_func, j'ai été en mesure de reconstituer ce qui précède. Notez également que $params sous forme de tableau ne fonctionne pas pour moi:

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

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

12
Chris K

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

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

Cependant, call_user_func() est la bonne manière.

10
karim79

Noms de fonctions dynamiques et espaces de noms

Juste pour ajouter un point sur les noms de fonctions dynamiques lors de l'utilisation d'espaces de noms.

Si vous utilisez des espaces de noms, ce qui suit ne fonctionnera pas sauf si votre fonction est dans l'espace de noms global:

namespace greetings;

function hello()
{
    // do something
}

$myvar = "hello";
$myvar(); // interpreted as "\hello();"

Que faire?

Vous devez utiliser call_user_func() à la place:

// if hello() is in the current namespace
call_user_func(__NAMESPACE__.'\\'.$myvar);

// if hello() is in another namespace
call_user_func('mynamespace\\'.$myvar);
7
Jivan

Il existe des possibilités impressionnantes à partir de PHP7. Initialement, comme d'autres l'ont mentionné, en PHP5 (et même plus ancien que PHP5), nous pouvions faire:

function something() {
    echo 256;
}

$foo = "something";
$foo(); // 256

C'est bien, mais cela s'est amélioré en PHP7. Nous pouvons effectuer des opérations arbitraires sur une ou plusieurs chaînes entre parenthèses et l’utiliser comme nom de la fonction en une seule opération (considérons que nous avons déclaré une fonction ()):

$bar = "some_thing";

// We use in this form: (expressions)(arguments);
(str_replace("_", "", $bar))(); // 256

De plus, vous pouvez utiliser tout le formulaire suivant:

(expressions)['bar']
(expressions)->bar
(expressions)->bar()
(expressions)->$bar()
(expressions)::$bar
(expressions)::bar()
(expressions)()

Par exemple, vous pouvez utiliser une combinaison de classes anonymes et de la fonctionnalité ci-dessus:

echo (new class {
    public $something = 512;
})->something; // 512

En outre, vous pouvez appeler une méthode sur une instance de classe sous la forme de:

[objectInstance, methodName]();

A titre d'exemple, nous pourrions faire:

class X {
    public function object_call() {
        echo "Object Call";
    }
    public static function static_call() {
        echo "Static Call";
    }
}

[new X(), "object_call"](); // Object Call
[new X(), "static_call"](); // Static Call

Extrait de this PHP talk .

6
MAChitgarha

Complétant la réponse de @Chris K si vous souhaitez appeler la méthode d'un objet, vous pouvez l'appeler en utilisant une seule variable à l'aide d'une fermeture:

function get_method($object, $method){
    return function() use($object, $method){
        $args = func_get_args();
        return call_user_func_array(array($object, $method), $args);           
    };
}

class test{        

    function echo_this($text){
        echo $text;
    }
}

$test = new test();
$echo = get_method($test, 'echo_this');
$echo('Hello');  //Output is "Hello"

J'ai posté un autre exemple ici

3
David

Utilisez la fonction call_user_func.

2
PaulJWilliams

Ce que j'ai appris de cette question et des réponses. Merci a tous!

Disons que j'ai ces variables et fonctions:

_$functionName1 = "sayHello";
$functionName2 = "sayHelloTo";
$functionName3 = "saySomethingTo";

$friend = "John";
$datas = array(
    "something"=>"how are you?",
    "to"=>"Sarah"
);

function sayHello()
{
echo "Hello!";
}

function sayHelloTo($to)
{
echo "Dear $to, hello!";
}

function saySomethingTo($something, $to)
{
echo "Dear $to, $something";
}
_
  1. Pour appeler la fonction sans arguments

    _// Calling sayHello()
    call_user_func($functionName1); 
    _

    Salut!

  2. Pour appeler la fonction avec 1 argument

    _// Calling sayHelloTo("John")
    call_user_func($functionName2, $friend);
    _

    Cher John, bonjour!

  3. Pour appeler la fonction avec 1 ou plusieurs arguments Cela sera utile si vous appelez dynamiquement vos fonctions et que chaque fonction a un nombre différent d'arguments. C'est mon cas que j'ai cherché (et résolu). call_user_func_array est la clé

    _// You can add your arguments
    // 1. statically by hard-code, 
    $arguments[0] = "how are you?"; // my $something
    $arguments[1] = "Sarah"; // my $to
    
    // 2. OR dynamically using foreach
    $arguments = NULL;
    foreach($datas as $data) 
    {
        $arguments[] = $data;
    }
    
    // Calling saySomethingTo("how are you?", "Sarah")
    call_user_func_array($functionName3, $arguments);
    _

    Chère Sarah, comment vas-tu?

Yay au revoir!

2
asmasyakirah

Le code suivant peut aider à écrire une fonction dynamique en PHP. le nom de la fonction peut maintenant être modifié dynamiquement par la variable '$ current_page'.

$current_page = 'home_page';
$function = @${$current_page . '_page_versions'};
$function = function() {
    echo 'current page';
};
$function();
1
rakesh.falke