Search code examples
phpphp-5.3php-5.4php-5.5php-5.6

How does PHP interpret and evaluate function and anonymous function when passed as an argument?


I am a experience developer in PHP, I already know what is a function and what is a anonymous function. I also know what is the use of anonymous function and functions in PHP or in other languages. I also know the difference between function and anonymous functions.

Defination of anynonymous function is available at: http://php.net/manual/en/functions.anonymous.php

I got the use cases of anonymous function here: Why and how do you use anonymous functions in PHP?

But My question is how does PHP interpret/evaluate functions as arguments?

Consider below example:

<?php

function callFunction($function)
{
    $function();
}

//normal function
function test()
{
    echo "here";
}

//anonymous function
$function = function () {
    echo 'here';
};

//call normal function test
callFunction('test');

//call anonymous function $function
callFunction($function);

In above example both function are producing same output.

But I want to know how PHP execute/interpret/evaluate both functions in callFunction method. I researched on search engins for the same but unable to found exact answer which can explain the same correctly. Please help me to understand these two cases.


Solution

  • Let's see the two cases separately:

    <?php
    
    function callFunction($function)
    {
        $function();
    }
    
    //normal function
    function test()
    {
        echo "here";
    }
    
    //call normal function test
    callFunction('test');
    

    In this case the actual parameter for callFunction is the value "here", so a string value is passed. However, the syntax of PHP supports the concept of making it a dynamic function call: variable functions.

    PHP supports the concept of variable functions. This means that if a variable name has parentheses appended to it, PHP will look for a function with the same name as whatever the variable evaluates to, and will attempt to execute it. Among other things, this can be used to implement callbacks, function tables, and so forth.

    Now, onto the second case:

    <?php
    
    function callFunction($function)
    {
        $function();
    }
    
    //anonymous function
    $function = function () {
        echo 'here';
    };
    
    //call anonymous function $function
    callFunction($function);
    

    In this case $function is a Closure, as it is mentioned in the reference you linked. It is the implemented way of the function object concept in PHP. The received Closure is then executed with the parentheses operator.

    You may even enforce the parameter typing in order to separate it into two different cases with type hinting:

    // NOTE: string type hinting only available since PHP7
    function callFunction_string(string $function)
    {
        $function();
    }
    
    function callFunction_closure(Closure $function)
    {
        $function();
    }
    

    So basically the type of the parameter received by callFunction is entirely different (string vs. Closure), however the PHP syntax is the same for both of them to execute a function call. (It's not a coincidence, it was designed like that.)

    Note: similar solutions are widespread in programming languages, even in strongly typed languages like C++: just look at how function pointers, functors and lamda objects can be passed as an - templated - argument to a function, and then executed with the parentheses operator.