web-dev-qa-db-fra.com

Pouvez-vous stocker une fonction dans un tableau PHP?

par exemple.:

$functions = array(
  'function1' => function($echo) { echo $echo; }
);

Est-ce possible? Quelle est la meilleure alternative?

61
Kirk Ouimet

Il y a quelques options. Utilisation create_function :

$functions = array(
  'function1' => create_function('$echo', 'echo $echo;')
);

Enregistrez simplement le nom de la fonction sous forme de chaîne (c'est en fait tout create_function fait):

function do_echo($echo) {
    echo $echo;
}

$functions = array(
  'function1' => 'do_echo'
);

Si vous utilisez PHP 5.3 vous pouvez utiliser fonctions anonymes :

$functions = array(
  'function1' => function($echo) {
        echo $echo;
   }
);

Toutes ces méthodes sont répertoriées dans la documentation sous le pseudo-type callback . Quel que soit votre choix, la manière recommandée d'appeler votre fonction serait soit avec le call_user_func ou call_user_func_array fonction.

call_user_func($functions['function1'], 'Hello world!');
139
Alex Barrett

Depuis PHP "5.3.0 Des fonctions anonymes deviennent disponibles", exemple d'utilisation:

notez que c'est beaucoup plus rapide que d'utiliser l'ancien create_function...

//store anonymous function in an array variable e.g. $a["my_func"]
$a = array(
    "my_func" => function($param = "no parameter"){ 
        echo "In my function. Parameter: ".$param;
    }
);

//check if there is some function or method
if( is_callable( $a["my_func"] ) ) $a["my_func"](); 
    else echo "is not callable";
// OUTPUTS: "In my function. Parameter: no parameter"

echo "\n<br>"; //new line

if( is_callable( $a["my_func"] ) ) $a["my_func"]("Hi friend!"); 
    else echo "is not callable";
// OUTPUTS: "In my function. Parameter: Hi friend!"

echo "\n<br>"; //new line

if( is_callable( $a["somethingElse"] ) ) $a["somethingElse"]("Something else!"); 
    else echo "is not callable";
// OUTPUTS: "is not callable",(there is no function/method stored in $a["somethingElse"])

RÉFÉRENCES:

10
jave.web

Pour suivre le message d'Alex Barrett, create_function () renvoie une valeur que vous pouvez réellement utiliser pour appeler la fonction, donc:

$function = create_function('$echo', 'echo $echo;' );
$function('hello world');
9
RibaldEddie

Parce que je pourrais ...

Expansion sur le poste d'Alex Barrett.

Je travaillerai à affiner davantage cette idée, peut-être même à quelque chose comme une classe statique externe, en utilisant éventuellement le jeton "..." pour autoriser les arguments de longueur variable.

Dans l'exemple suivant, j'ai utilisé le mot-clé "tableau" pour plus de clarté, mais les crochets seraient également très bien. La disposition illustrée qui utilise une fonction init est destinée à démontrer l'organisation d'un code plus complexe.

<?php
// works as per php 7.0.33

class pet {
    private $constructors;

    function __construct() {
        $args = func_get_args();
        $index = func_num_args()-1;
        $this->init();

        // Alex Barrett's suggested solution
        // call_user_func($this->constructors[$index], $args);  

        // RibaldEddie's way works also
        $this->constructors[$index]($args); 
    }

    function init() {
        $this->constructors = array(
            function($args) { $this->__construct1($args[0]); },
            function($args) { $this->__construct2($args[0], $args[1]); }
        );
    }

    function __construct1($animal) {
        echo 'Here is your new ' . $animal . '<br />';
    }

    function __construct2($firstName, $lastName) {
        echo 'Name-<br />';
        echo 'First: ' . $firstName . '<br />';
        echo 'Last: ' . $lastName;
    }
}

$t = new pet('Cat');
echo '<br />';
$d = new pet('Oscar', 'Wilding');
?>

Ok, raffiné en une seule ligne maintenant comme ...

function __construct() {
    $this->{'__construct' . (func_num_args()-1)}(...func_get_args());
}

Peut être utilisé pour surcharger n'importe quelle fonction, pas seulement les constructeurs.

0
Stuperfied