আগামী ২৩ অক্টোবর -২০১৭ তারিখ থেকে শুরু হচ্ছে পাঁচ মাস ব্যাপী Professional Web Design and Development with HTML,CSS,Bootstrap,PHP,MySQl, AJAX and JQUERY কোর্সের ৮৬ তম ব্যাচ। আগ্রহীদেরকে অতিসত্বর মাসুদ আলম স্যার এর সাথে যোগাযোগ করতে অনুরোধ করা যাচ্ছে। স্যার এর মোবাইল: 01722817591, Email : [email protected] কোর্সের সিলেবাস এর জন্য এখানে ক্লিক করুন ।

PHP Object-Oriented Programming Part-7 (Anonymous Functions and Closures)

[printfriendly]
php-anonymous-functions

In this tutorial you’ll explore anonymous functions in PHP. Anonymous functions are a PHP feature that you probably won’t use that often; however, they can be really useful in certain situations, as you’ll see.

You’ll look at the following concepts in this tutorial:

  1. What anonymous functions are, and how you create them
  2. How to assign anonymous functions to variables
  3. How to call anonymous functions
  4. Using anonymous functions to create neater callbacks, and
  5. Creating closures with anonymous functions.

Ready to dive into anonymous functions in PHP? Let’s go!
Anonymous functions explained

function myFunctionName() {
  // (Your function code goes here)
}

When you define a function, you give it a name (myFunctionName in the above example). PHP then lets your code refer to this function using its name. For example, you can call your function like this:

myFunctionName();

Anonymous functions are similar to regular functions, in that they contain a block of code that is run when they are called. They can also accept arguments, and return values.

The key difference — as their name implies — is that anonymous functions have no name. Here’s a code example that creates a simple anonymous function:

// Declare a basic anonymous function
// (not much use on its own!)
function( $name, $timeOfDay ) {
return ( 'Good $timeOfDay, $name!' );
};

There are two subtle but important differences between the above example and a regular function definition:

There is no function name between the function keyword and the opening parenthesis (‘(‘). This tells PHP that you’re creating an anonymous function.
There is a semicolon after the function definition. This is because anonymous function definitions are expressions, whereas regular function definitions are code constructs.

While the above code is perfectly valid, it isn’t very useful. Since the anonymous function has no name, you can’t refer to it anywhere else in your code, so it can never be called!

However, since an anonymous function is an expression — much like a number or a string — you can do various handy things with it. For example, you can:

Assign it to a variable, then call it later using the variable’s name. You can even store a bunch of different anonymous functions in a single array.
Pass it to another function that can then call it later. This is known as a callback.
Return it from within an outer function so that it can access the outer function’s variables. This is known as a closure.

You’ll explore these three techniques in the rest of this tutorial.
Assigning anonymous functions to variables

When you define an anonymous function, you can then store it in a variable, just like any other value. Here’s an example:

// Assign an anonymous function to a variable
$makeGreeting = function( $name, $timeOfDay ) {
  return ( 'Good $timeOfDay, $name!' );
};

Once you’ve done that, you can call the function using the variable’s name, just like you call a regular function:

// Call the anonymous function
echo $makeGreeting( 'Omran', 'morning' ) . '
';
echo $makeGreeting( 'ShiShir', 'afternoon' ) . '
';

This produces the output:

Good morning, Omran!
Good afternoon, ShiShir!

You can even store several functions inside an array, like this:

// Store 3 anonymous functions in an array
$luckyDip = array(

function() {
echo 'You got a bag of toffees!';
},

function() {
echo 'You got a toy car!';
},

function() {
echo 'You got some balloons!';
}
);

Once you’ve done that, your code can decide which function to call at runtime. For example, it could call a function at random:

// Call a random function
$choice = rand( 0, 2 );
$luckyDip[$choice]();

Using anonymous functions as callbacks

One common use of anonymous functions is to create simple inline callback functions. A callback function is a function that you create yourself, then pass to another function as an argument. Once it has access to your callback function, the receiving function can then call it whenever it needs to. This gives you an easy way to customise the behaviour of the receiving function.

Many built-in PHP functions accept callbacks, and you can also write your own callback-accepting functions. Let’s look at a couple of built-in functions that use callbacks, and see how to use them.

Using array_map() to run a callback function on each element in an array

PHP’s array_map() function accepts a callback function and an array as arguments. It then walks through the elements in the array. For each element, it calls your callback function with the element’s value, and your callback function needs to return the new value to use for the element. array_map() then replaces the element’s value with your callback’s return value. Once it’s done, array_map() returns the modified array.

Note: array_map() works on a copy of the array you pass to it. The original array is untouched.

Here’s how you might use array_map() with a regular callback function:

// Create a regular callback function...
function nameToGreeting( $name ) {
return 'Hello ' . ucfirst( $name ) . '!';
}

// ...then map the callback function to elements in an array.
$names = array( 'Omran', 'ShiShir', 'Badol' );
print_r( array_map( nameToGreeting, $names ) );

This code creates a regular function, nameToGreeting(), that takes a string, $name, uppercases the first letter, prepends “Hello “, and returns the result. Then, on line 8, the code passes this callback function to array_map(), along with an array of names to work with, and displays the result:

Output:
Array ( [0] =>; Hello Omran! [1] =>; Hello ShiShir! [2] =>; Hello Badol! )

While this code works, it’s a bit cumbersome to create a separate regular function just to act as a simple callback like this. Instead, we can create our callback as an inline anonymous function at the time we call array_map(), as follows:

// A neater way:
// Map an anonymous callback function to elements in an array.
print_r ( array_map( function( $name ) {
return 'Hello ' . ucfirst( $name ) . '!';
}, $names ) );

This approach saves a line of code, but more importantly, it avoids cluttering up the PHP file with a separate regular function that is only being used as a one-off callback.

Custom array sorting with usort()

Another common use of callbacks is with PHP’s usort() function. This function lets you sort arrays using a sorting callback function that you write yourself. This is particularly handy if you need to sort an array of objects or associative arrays, since only you, as the coder, know the best way to sort such complex structures.

Let’s create an array of associative arrays, where each associative array has a name key and an age key:

$people = array(
  array( 'name' =>; 'Omran', 'age' =>; 39 ),
  array( 'name' =>; 'ShiShir', 'age' =>; 23 ),
  array( 'name' =>; 'Badol', 'age' =>; 46 )
);

Now, say we want to sort the array in ascending order of age. We can’t use the regular PHP array sorting functions, since these don’t know anything about the age key. Instead, we can call usort() and pass in an anonymous callback function that sorts the array by age, like this:

usort( $people, function( $personA, $personB ) {
return ( $personA['age'] < $personB['age'] ) ? -1 : 1;
} );

print_r( $people );

This produces the result we want:

Output:

Array (
[0] =>; Array ( [name] =>; Shishir[age] =>; 23 )
[1] =>; Array ( [name] =>; Omran[age] =>; 39 )
[2] =>; Array ( [name] =>; Badol[age] =>; 46 )
)

Closures

In the examples so far, anonymous functions have been assigned to a variable, and passed as arguements to a function. This is not really a closure, although, PHP types all anonymous functions as a closure. Confused? Good. Lets resolve this with some code.

<?php
function myClosure( $num ) {
return function( $x ) use( $num ){
return $num * $x;
};
}

$closure = myClosure( 10 );
echo $closure( 2 ).'\n';
echo $closure( 3 ).'\n';
?>

The output of the above code is 20 and 30. The myClosure function is assigned to a variable, which, in essence, is not the function and can be used anywhere throughout the code in the same way as a function.

Now lets get complete closure.

<?php
function myClosure() {
$local_var = 10;
return function() use (&amp;$local_var) {
return ++$local_var;
};
}

// create a closure
$my_closure = myClosure();

// call the closure
echo $my_closure().'\n';
echo $my_closure().'\n';
echo $my_closure().'\n';

// a random closure
$random_closure = myClosure();
echo $random_closure().'\n';

// back to my_closure
echo $my_closure();

The output of the above code will be like this:

11
12
13
11
14

What devilry is this?
Lets take a closer look at what has happened here.. A local variable named $local_var has been assigned the value of 10, just as would be done in any function. Within the anonymous function, the use() call is used to bind or close over the variable to create the closure.

The closure retains a reference to $local_var at all times, even after the function returns, which would normally see the variable fall out of lexical scope.

So, when the first three calls are made using the closure, the number increments. Then a new $random_closure is created which does not contain the reference, only $my_closure() contains the initial reference, and so, when this is again called at the end, the number 14 is returned.

So, if another call was added to $random_closure, what would the output be? This is left as an exercise to the reader.

PHP Object-Oriented Programming Part-7

Hi, My name is Masud Alam, love to work with Open Source Technologies, living in Dhaka, Bangladesh. I graduated in 2009 with a bachelor's degree in Engineering from State University Of Bangladesh, I'm also a Certified Engineer on ZEND PHP 5.3, I served my first five years a number of leadership positions at Winux Soft Ltd, SSL Wireless Ltd, CIDA and MAX Group where I worked on ERP software and web development., but now i'm a co-founder and Chief Executive Officer and Managing Director of TechBeeo Software Consultancy Services Ltd. I'm also a Course Instructor of ZCPE PHP 7 Certification and professional web development course at w3programmers Training Institute - a leading Training Institute in the country.
One comment on “PHP Object-Oriented Programming Part-7 (Anonymous Functions and Closures)
  1. hello, first I’d like to congradulate you on an excellent tutorial. I’m just starting with php and this tutorial looks like something I’ll come back to and use to do some good stuff. now to my problem, in this last closure there is a piece of code that I dont get and it doesnt work here. ” use (&$local_var)”, gets me a parse error, saying that this “amp” in not expected. can you tell me what to do to fix this?

    thank you very much

Leave a Reply

Your email address will not be published. Required fields are marked *