Anonymous functions

Anonymous functions, or lambda functions, are functions without a name. As they do not have a name, in order to be able to invoke them, we need to store them as variables. It might be strange at the beginning, but the idea is quite simple. At this point of time, we do not really need any anonymous function, so let's just add the code into init.php, and then remove it:

$addTaxes = function (array &$book, $index, $percentage) {
    $book['price'] += round($percentage * $book['price'], 2);
};

This preceding anonymous function gets assigned to the variable $addTaxes. It expects three arguments: $book (an array as a reference), $index (not used), and $percentage. The function adds taxes to the price key of the book, rounded to 2 decimal places (round is a native PHP function). Do not mind the argument $index, it is not used in this function, but forced by how we will use it, as you will see.

You could instantiate a list of books as an array, iterate them, and then call this function each time. An example could be as follows:

$books = [
    ['title' => '1984', 'price' => 8.15],
    ['title' => 'Don Quijote', 'price' => 12.00],
    ['title' => 'Odyssey', 'price' => 3.55]
];
foreach ($books as $index => $book) {
    $addTaxes($book, $index, 0.16);
}
var_dump($books);

In order to use the function, you just invoke it as if $addTaxes contained the name of the function to be invoked. The rest of the function works as if it was a normal function: it receives arguments, it can return a value, and it has a scope. What is the benefit of defining it in this way? One possible application would be to use it as a callable. A callable is a variable type that identifies a function that PHP can call. You send this callable variable as an argument, and the function that receives it can invoke it. Take the PHP native function, array_walk. It gets an array, a callable, and some extra arguments. PHP will iterate the array, and for each element, it will invoke the callable function (just like the foreach loop). So, you can replace the whole loop by just the following:

array_walk($books, $addTaxes, 0.16);

The callable that array_walk receives needs to take at least two arguments: the value and the index of the current element of the array, and thus, the $index argument that we were forced to implement previously. It can optionally take extra arguments, which will be the extra arguments sent to array_walk—in this case, the 0.16 as $percentage.

Actually, anonymous functions are not the only callable in PHP. You can send normal functions and even class methods. Let's see how:

function addTaxes(array &$book, $index, $percentage) {
    if (isset($book['price'])) {
        $book['price'] += round($percentage * $book['price'], 2);
    }
}

class Taxes {
    public static function add(array &$book, $index, $percentage)
    {
        if (isset($book['price'])) {
            $book['price'] += round($percentage * $book['price'], 2);
        }
    }
    public function addTaxes(array &$book, $index, $percentage)
    {
        if (isset($book['price'])) {
            $book['price'] += round($percentage * $book['price'], 2);
        }
    }
}

// using normal function
array_walk($books, 'addTaxes', 0.16);
var_dump($books);

// using static class method
array_walk($books, ['Taxes', 'add'], 0.16);
var_dump($books);

// using class method
array_walk($books, [new Taxes(), 'addTaxes'], 0.16);
var_dump($books);

In the preceding example, you can see how we can use each case as a callable. For normal methods, just send the name of the method as a string. For static methods of a class, send an array with the name of the class in a way that PHP understands (either the full name including namespace, or adding the use keyword beforehand), and the name of the method, both as strings. To use a normal method of a class, you need to send an array with an instance of that class and the method name as a string.

OK, so anonymous functions can be used as callable, just as any other function or method can. So what is so special about them? One of the things is that anonymous functions are variables, and so they have all the advantages—or disadvantages—that a variable has. That includes scope—that is, the function is defined inside a scope, and as soon as this scope ends, the function will no longer be accessible. That can be useful if your function is extremely specific to that bit of code, and there is no way you will want to reuse it somewhere else. Moreover, as it is nameless, you will not have conflicts with any other existing function.

There is another benefit in using anonymous functions: inheriting variables from the parent scope. When you define an anonymous function, you can specify some variable from the scope where it is defined with the keyword use, and use it inside the function. The value of the variable will be the one it had at the moment of declaring the function, even if it is updated later. Let's see an example:

$percentage = 0.16;
$addTaxes = function (array &$book, $index) use ($percentage) {
    if (isset($book['price'])) {
        $book['price'] += round($percentage * $book['price'], 2);
    }
};
$percentage = 100000;
array_walk($books, $addTaxes);
var_dump($books);

The preceding example shows you how to use the keyword use. Even when we update $percentage after defining the function, the result shows you that the taxes were only 16%. This is useful, as it liberates you from having to send $percentage everywhere you want to use the function $addTaxes. If there is a scenario where you really need to have the updated value of the used variables, you can declare them as a reference as you would with a normal function's argument:

$percentage = 0.16;
$addTaxes = function (array &$book, $index) use (&$percentage) {
    if (isset($book['price'])) {
        $book['price'] += round($percentage * $book['price'], 2);
    }
};

array_walk($books, $addTaxes, 0.16);
var_dump($books);

$percentage = 100000;
array_walk($books, $addTaxes, 0.16);
var_dump($books);

In this last example, the first array_walk used the original value 0.16, as that was still the value of the variable. But on the second call, $percentage had already changed, and it affected the result of the anonymous function.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.138.120.187