ProgrammingPHP 5.3 Closures and their uses

PHP 5.3 Closures and their uses

As of PHP 5.3 you can now use something known as a closure in your php code. In PHP a closure is simply an anonymous function.
Here is an example of a closure

$upperCaseName = function($name){
return ucfirst($name);
};

which means that later on you can use this variable in the following way:

$name = "rachel";
$newName = $upperCaseName($name);
echo $newName;

This will output “Rachel”

None of the above is particularly useful. However there are some benefits to this as shown below.

If we have an array of Objects, from time to time we may want to perform a method on each of these objects and perhaps gather the result into a new array a closure can make this
into essentially a one liner. In the code below, I will first define a small class, then make some instances of the class and add them to an array. Then I will use a closure to perform a method on each object returning the result to a new array.


//first the basic class we want to make objects from and perform methods on
class person{
private $name;
public function __construct($name){
$this->name = $name;
}

public function cappedName(){
return ucfirst($this->name);
}
}

//an array of people
$person1 = new Person("peter");
$person2 = new Person("james");
$people = array($person1, $person2)

$resultArray = array();
//now the closure
array_map(function($row)use(&$resultArray){$resultArray[] = $row->cappedName();},$people);

print_r($resultArray);

//the output will be array([0]=>"Peter",[1]=>"James")

So to explain the above code: array_map is a normal php function which takes a callback function and an array. It then applies the call back to each element of the array. Normally we would have to define an external function and use that as the call back parameter, but with a closure there is no need as the function can be defined anonymously as the argument.
So in our closure we have an argument $row and then the “use” keyword. The “use” keyword allows our closure access to the external array $resultArray, we also use the & operator to pass it by reference. The body of our function is then simply assigning the return value of the call to $row->cappedName() into the $resultArray which can then be used for whatever purpose you may see fit.

A final interesting point about Closures is that they can be used as a Type. In other words when defining a function or method you can specify that the argument passed needs to be a Closure.
In the code below we ask for a Closure to use to format a name.

function formatName($name, Closure $closure = null){
if(! $closure){
$closure = function($val){ return ucfirst($val);}
}

return $closure($name);

}

So this code would allow the following:


$formatter = function($val){ return strtolower($val);}

$newName = formatName("JOHN",$formatter);

//this would return "john"

I hope that you have found this helpful. Happy coding in the future.

Regards Craig

Developer Hostingireland