web-dev-qa-db-fra.com

PHP passer la fonction en tant que param puis appeler la fonction?

J'ai besoin de passer une fonction en tant que paramètre à une autre fonction, puis d'appeler la fonction passée à l'intérieur de la fonction ... C'est probablement plus facile pour moi d'expliquer dans le code..Je veux fondamentalement faire quelque chose comme ça:

function ($functionToBeCalled)
{
   call($functionToBeCalled,additional_params);
}

Existe-t-il un moyen de le faire? J'utilise PHP 4.3.9

Merci!

43
JD Isaacks

Je pense que vous recherchez call_user_func .

Un exemple tiré du manuel PHP:

<?php
function barber($type) {
    echo "You wanted a $type haircut, no problem";
}
call_user_func('barber', "mushroom");
call_user_func('barber', "shave");
?>
78
Paolo Bergantino
function foo($function) {
  $function(" World");
}
function bar($params) {
  echo "Hello".$params;
}

$variable = 'bar';
foo($variable);

De plus, vous pouvez le faire de cette façon. Voir fonctions variables .

26
tj111

En php c'est très simple.

<?php

function here() {
  print 'here';
}


function dynamo($name) {
 $name();
}

//Will work
dynamo('here');
//Will fail
dynamo('not_here');
25
Stewart Robinson

Vous pouvez également utiliser call_user_func_array() . Il vous permet de transmettre un tableau de paramètres en tant que deuxième paramètre, de sorte que vous ne devez pas savoir exactement combien de variables vous transmettez.

11
Rick

Je connais la question initiale posée à propos de PHP 4.3, mais quelques années plus tard, je souhaitais simplement préconiser la méthode que je préfèrerais utiliser dans PHP 5.3 ou une version ultérieure.

PHP 5.3+ inclut maintenant le support des fonctions anonymes (fermetures) , vous pouvez donc utiliser certaines techniques de programmation fonctionnelles standard, comme dans des langages tels que JavaScript et Ruby (avec quelques mises en garde). La réécriture de l'exemple call_user_func ci-dessus dans "style de fermeture" ressemblerait à ceci, que je trouve plus élégant:

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

$barber('mushroom');
$barber('shave');

Évidemment, cela ne vous rapporte pas grand chose dans cet exemple: le pouvoir et la flexibilité découlent du transfert de ces fonctions anonymes à d'autres fonctions (comme dans la question initiale). Ainsi, vous pouvez faire quelque chose comme:

$barber_cost = function($quantity) {
    return $quantity * 15;
};

$candy_shop_cost = function($quantity) {
    return $quantity * 4.50;   // It's Moonstruck chocolate, ok?
};

function get_cost($cost_fn, $quantity) {
    return $cost_fn($quantity);
}

echo '3 haircuts cost $' . get_cost($barber_cost, 3) . "\n";
echo '6 candies cost $' . get_cost($candy_shop_cost, 6) . "\n";

Cela pourrait être fait avec call_user_func, bien sûr, mais je trouve cette syntaxe beaucoup plus claire, en particulier une fois que les espaces de noms et les variables membres sont impliqués.

Une mise en garde: je serai le premier à admettre que je ne sais pas exactement ce qui se passe ici, mais vous ne pouvez pas toujours appeler une fermeture contenue dans un membre ou une variable statique, et éventuellement dans d'autres cas. Mais sa réaffectation à une variable locale lui permettra d'être invoquée. Ainsi, par exemple, cela vous donnera une erreur:

$some_value = \SomeNamespace\SomeClass::$closure($arg1, $arg2);

Mais cette solution de contournement simple résout le problème:

$the_closure = \SomeNamespace\SomeClass::$closure;
$some_value = $the_closure($arg1, $arg2);
9
mercurial

Si vous avez besoin d'une fonction pass avec un paramètre comme paramètre, vous pouvez essayer ceci:

function foo ($param1){
   return $param1;
}

function bar ($foo_function, $foo_param){
    echo $foo_function($foo_param);
}

//call function bar
bar('foo', 'Hi there');  //this will print: 'Hi there'

exemple phpfiddle

J'espère que ça va être utile ...

6
waLL e

Si vous voulez faire cela dans une classe PHP, regardez ce code:

// Create a sample class
class Sample
{

    // Our class displays 2 lists, one for images and one for paragraphs
    function __construct( $args ) {
        $images = $args['images'];
        $items  = $args['items'];
        ?>
        <div>
            <?php 
            // Display a list of images
            $this->loop( $images, 'image' ); 
            // notice how we pass the name of the function as a string

            // Display a list of paragraphs
            $this->loop( $items, 'content' ); 
            // notice how we pass the name of the function as a string
            ?>
        </div>
        <?php
    }

    // Reuse the loop
    function loop( $items, $type ) {
        // if there are items
        if ( $items ) {
            // iterate through each one
            foreach ( $items as $item ) {
                // pass the current item to the function
                $this->$type( $item ); 
                // becomes $this->image 
                // becomes $this->content
            }
        }
    }

    // Display a single image
    function image( $item ) {
        ?>
        <img src="<?php echo $item['url']; ?>">
        <?php 
    }

    // Display a single paragraph
    function content( $item ) {
        ?>
        <p><?php echo $item; ?></p>
        <?php 
    }
}

// Create 2 sample arrays
$images = array( 'image-1.jpg', 'image-2.jpg', 'image-3.jpg' );
$items  = array( 'sample one', 'sample two', 'sample three' );

// Create a sample object to pass my arrays to Sample
$elements = { 'images' => $images, 'items' => $items }

// Create an Instance of Sample and pass the $elements as arguments
new Sample( $elements );
0
drjorgepolanco