简体   繁体   中英

PHP pass function name as param then call the function?

I need to pass a function as a parameter to another function and then call the passed function from within the function...This is probably easier for me to explain in code..I basically want to do something like this:

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

Is there a way to do that.. I am using PHP 4.3.9

Thanks!

I think you are looking for call_user_func .

An example from the PHP Manual:

<?php
function barber($type) {
    echo "You wanted a $type haircut, no problem";
}
call_user_func('barber', "mushroom");
call_user_func('barber', "shave");
?>

In php this is very simple.

<?php

function here() {
  print 'here';
}


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

//Will work
dynamo('here');
//Will fail
dynamo('not_here');
function foo($function) {
  $function(" World");
}
function bar($params) {
  echo "Hello".$params;
}

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

Additionally, you can do it this way. See variable functions .

I know the original question asked about PHP 4.3, but now it's a few years later and I just wanted to advocate for my preferred way to do this in PHP 5.3 or higher.

PHP 5.3+ now includes support for anonymous functions (closures) , so you can use some standard functional programming techniques, as in languages like JavaScript and Ruby (with a few caveats). Rewriting the call_user_func example above in "closure style" would look like this, which I find more elegant:

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

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

Obviously, this doesn't buy you much in this example - the power and flexibility comes when you pass these anonymous functions to other functions (as in the original question). So you can do something like:

$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";

This could be done with call_user_func, of course, but I find this syntax much clearer, especially once namespaces and member variables get involved.

One caveat: I'll be the first to admit I don't know exactly what's going on here, but you can't always call a closure contained in a member or static variable, and possibly in some other cases. But reassigning it to a local variable will allow it to be invoked. So, for example, this will give you an error:

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

But this simple workaround fixes the issue:

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

You could also use call_user_func_array() . It allows you to pass an array of parameters as the second parameter so you don't have to know exactly how many variables you're passing.

If you need pass function with parameter as parameter, you can try this:

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'

phpfiddle example

Hope it'll be helpful...

If you want to do this inside a PHP Class, take a look at this 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 );

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM