Accept function as parameter in PHP

PhpFunction

Php Problem Overview


I've been wondering whether is possible or not to pass a function as parameter in PHP; I want something like when you're programming in JS:

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

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

Php Solutions


Solution 1 - Php

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();
}

Solution 2 - Php

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.

Solution 3 - Php

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.

Solution 4 - Php

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();
});

Solution 5 - Php

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) {}

Solution 6 - Php

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;
});

Solution 7 - Php

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)*/
?>

Solution 8 - Php

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;


});

Solution 9 - Php

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);
?>

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionCristianView Question on Stackoverflow
Solution 1 - PhpzombatView Answer on Stackoverflow
Solution 2 - PhpwebbiedaveView Answer on Stackoverflow
Solution 3 - PhpJageView Answer on Stackoverflow
Solution 4 - PhpSaint NightView Answer on Stackoverflow
Solution 5 - PhpNick TsaiView Answer on Stackoverflow
Solution 6 - PhpDavit GabrielyanView Answer on Stackoverflow
Solution 7 - PhpMarco OttinaView Answer on Stackoverflow
Solution 8 - PhpSoftmixtView Answer on Stackoverflow
Solution 9 - PhpIan HollenderView Answer on Stackoverflow