Lambdas and closures in PHP 5.3

Beginning with PHP 5.3 we’ll be able to write anonymous functions and build closures around them - almost the same way we do it in JavaScript. I’d like to introduce these to those of you unaware of these new possibilities in this little blog post.

Defining a lambda

The most simple way to define a lambda can be find below. It’s exactly the same way JavaScript handles it. One has to assing a function to a variable.

<?php

$lambda = function() {
    return 'Hello World';
}; // <- this semicolon is mandatory, unlike JavaScript

echo $lambda();

Creating closures

However, if we want closures, we have to do something more and this because the way scope is designed in PHP where functions don’t get easy access to variables declared outside them. If we want that with a normal (old style) function, we need to import them using the global keyword. Following the same idea, in order to capture a variable into a closure we need to use it:

<?php

$word = ' World';
$lambda = function() use($word) {
    return 'Hello' . $word;
};

echo $lambda();

Mutable closures

Now, our anonymous functions has access to $word. But there’s a gotcha right here. It has read only access to $word. We may try to modify $word inside our function, but those changes won’t be visible outside it. So, here we are, introducing the third thing we need to know about lambdas and closures in PHP. In order to be able to modify a closed variable, we need to import it using the reference operator:

<?php

$word = ' World';
$lambda = function() use(& $word) {
    $result = 'Hello' . $word;
    $word = 'Bye World';
    return $result;
};

echo $lambda();
echo $word;

This time, $word can and will be modified. The variable inside the closure is mutable.

Some history about the future

Although, as of yet, a stable version of PHP 5.3 is not yet out, I should mention that in the process of bringing lambdas and closures to the language there was a particular property of these in that they were able to automagically import the $this pointer if the function was defined inside a class. Not long after, some people thought about writing PHP in the prototypal style of JavaScript, thus there were some discussion that lead the PHP internals to temporarily remove the magic import feature. The main reason was that they had to push the final version out sooner and any new feature would have meant delays. Nevertheless, this feature has been postponed for PHP 6 in which we may get some niceties that should allow us to more easily write code in a monkey patching/prototypal style.