136

I've been wondering whether it is possible or not to pass a function as a parameter in PHP. I want something similar to when you're programming the following code in JavaScript:

object.exampleMethod(function(){
    // some stuff to execute
});

What I want is to execute that function somewhere in exampleMethod. Is that possible in PHP?

1

9 Answers 9

181

It's possible if you are using PHP 5.3.0 or higher.

See Anonymous Functions in the manual.

In your case, you would define exampleMethod like this:

function exampleMethod($anonFunc) {
    //execute anonymous function
    $anonFunc();
}
Sign up to request clarification or add additional context in comments.

7 Comments

Damn, I knew it was possible. Was going to answer, but wanted to find some documentation to link to first, and didn't know what it was called exactly. Ah well, now I'll know for when I need to do this as well. Thanks.
Prior to 5.3 you can use create_function
Thank you so much. Since I have to do it for PHP4.3 I guess I'll have to do what I want using another logic.
@Casidiablo - See Jage's answer, you might be able to do something with create_function(). It's not quite the same, as you have to pass your function as a string of code, which then gets eval()'d behind the scenes. Not ideal, but you might be able to use it.
How would you call it? Could you give a name of existing function? Eg: exampleMethod(strpos);
|
69

Just to add to the others, you can pass a function name:

function someFunc($a)
{
    echo $a;
}

function callFunc($name)
{
    $name('funky!');
}

callFunc('someFunc');

This will work in PHP4.

Comments

21

Valid: (PHP 4 >= 4.0.1, PHP 5, PHP 7)

You can also use create_function to create a function as a variable and pass it around. Though, I like the feeling of anonymous functions better. Go zombat.


Update 09 - Jan - 2022

Warning

This function has been DEPRECATED as of PHP 7.2.0, and REMOVED as of PHP 8.0.0. Relying on this function is highly discouraged.

3 Comments

+1 for the alternative. It sounds like the OP might need it.
Thanks! I've to stick with an old PHP 5.2 installation and anonymoys functions don't work there.
Warning: This function has been DEPRECATED as of PHP 7.2.0. Relying on this function is highly discouraged.
15

Just code it like this:

function example($anon) {
  $anon();
}

example(function(){
  // some codes here
});

it would be great if you could invent something like this (inspired by Laravel Illuminate):

Object::method("param_1", function($param){
  $param->something();
});

1 Comment

exactly what I was looking for
10

PHP VERSION >= 5.3.0

Example 1: basic

function test($test_param, $my_function) {
    return $my_function($test_param);
}

test("param", function($param) {
    echo $param;
}); //will echo "param"

Example 2: std object

$obj = new stdClass();
$obj->test = function ($test_param, $my_function) {
    return $my_function($test_param);
};

$test = $obj->test;
$test("param", function($param) {
    echo $param;
});

Example 3: non static class call

class obj{
    public function test($test_param, $my_function) {
        return $my_function($test_param);
    }
}

$obj = new obj();
$obj->test("param", function($param) {
    echo $param;
});

Example 4: static class call

class obj {
    public static function test($test_param, $my_function) {
        return $my_function($test_param);
    }
}

obj::test("param", function($param) {
    echo $param;
});

Comments

10

According to @zombat's answer, it's better to validate the Anonymous Functions first:

function exampleMethod($anonFunc) {
    //execute anonymous function
    if (is_callable($anonFunc)) {
        $anonFunc();
    }
}

Or validate argument type since PHP 5.4.0:

function exampleMethod(callable $anonFunc) {}

2 Comments

how do you handle when (callable $anonFunc) check failed? thanks
@xam you'll get a PHP TypeError. You can handle it inside a try-catch block. php.net/manual/en/class.typeerror.php
4

Tested for PHP 5.3

As i see here, Anonymous Function could help you: http://php.net/manual/en/functions.anonymous.php

What you'll probably need and it's not said before it's how to pass a function without wrapping it inside a on-the-fly-created function. As you'll see later, you'll need to pass the function's name written in a string as a parameter, check its "callability" and then call it.

The function to do check:

if( is_callable( $string_function_name ) ){
    /*perform the call*/
}

Then, to call it, use this piece of code (if you need parameters also, put them on an array), seen at : http://php.net/manual/en/function.call-user-func.php

call_user_func_array( "string_holding_the_name_of_your_function", $arrayOfParameters );

as it follows (in a similar, parameterless, way):

    function funToBeCalled(){
        print("----------------------i'm here");
    }
    function wrapCaller($fun){
        if( is_callable($fun)){
            print("called");
            call_user_func($fun);
        }else{
            print($fun." not called");
        }
    }

    wrapCaller("funToBeCalled");
    wrapCaller("cannot call me");

Here's a class explaining how to do something similar :

<?php
class HolderValuesOrFunctionsAsString{
    private $functions = array();
    private $vars = array();

    function __set($name,$data){
        if(is_callable($data))
            $this->functions[$name] = $data;
        else
            $this->vars[$name] = $data;
    }

    function __get($name){
        $t = $this->vars[$name];
        if(isset($t))
            return $t;
        else{
            $t = $this->$functions[$name];
            if( isset($t))
                return $t;
        }
    }

    function __call($method,$args=null){
        $fun = $this->functions[$method];
        if(isset($fun)){
            call_user_func_array($fun,$args);
        } else {
            // error out
            print("ERROR: Funciton not found: ". $method);
        }
    }
}
?>

and an example of usage

<?php
    /*create a sample function*/
    function sayHello($some = "all"){
    ?>
         <br>hello to <?=$some?><br>
    <?php
    }

    $obj = new HolderValuesOrFunctionsAsString;

    /*do the assignement*/
    $obj->justPrintSomething = 'sayHello'; /*note that the given
        "sayHello" it's a string ! */

    /*now call it*/
    $obj->justPrintSomething(); /*will print: "hello to all" and
        a break-line, for html purpose*/

    /*if the string assigned is not denoting a defined method
         , it's treat as a simple value*/
    $obj->justPrintSomething = 'thisFunctionJustNotExistsLOL';

    echo $obj->justPrintSomething; /*what do you expect to print?
        just that string*/
    /*N.B.: "justPrintSomething" is treated as a variable now!
        as the __set 's override specify"*/

    /*after the assignement, the what is the function's destiny assigned before ? It still works, because it's held on a different array*/
     $obj->justPrintSomething("Jack Sparrow");


     /*You can use that "variable", ie "justPrintSomething", in both ways !! so you can call "justPrintSomething" passing itself as a parameter*/

     $obj->justPrintSomething( $obj->justPrintSomething );
         /*prints: "hello to thisFunctionJustNotExistsLOL" and a break-line*/

    /*in fact, "justPrintSomething" it's a name used to identify both
         a value (into the dictionary of values) or a function-name
         (into the dictionary of functions)*/
?>

Comments

2

Simple example using a class :

class test {

    public function works($other_parameter, $function_as_parameter)
    {

        return $function_as_parameter($other_parameter) ;

    }

}

$obj = new test() ;

echo $obj->works('working well',function($other_parameter){


    return $other_parameter;


});

Comments

0

Here is a simple procedural example of how you could implement validation of multiple data items using separate functions for each data item validation, passed as an array of functions argument to a master validations function, with the data to be validated (the arguments to the functions) passes as the other array argument to the master validation function. Useful for writing generic code to validate form data.

<?php
function valX($value) {
    echo "<p>Validating $value == 5</p>";
    if ($value == 5) {
        return true;
    } else {
        return false;
    }
}

function valY($value) {
    echo "<p>Validating $value == 6</p>";
    if ($value == 6) {
        return true;
    } else {
        return false;
    }
}

function validate($values, $functions) {
    for ($i = 0; $i < count($values); $i++) {
        if ($functions[$i]($values[$i])) {
            echo "<p>$values[$i] passes validation</p>";
        } else {
            echo "<p>$values[$i] fails validation</p>";
        }
    }
}

$values = [5, 9];
$functions = ['valX', 'valY'];
validate($values, $functions);
?>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.