Lambdas (Anonymous functions), simply saying, are functions without a name. Anonymous functions are not new to php. We were able to write them from php4 onwards using create_function() function.
The problem here is body of our function will be a long quoted string which will be hard to manage and we will need to escape any quotes inside it. The same thing we will write as a lambda function as follows
I have said lambda functions won’t have a name and yet we gave a name to the function?. Remember it’s not a name of that function but just a reference to that function. Often we will be using lambdas as callback functions to other functions and there we won’t be giving any name. Though this simple example can’t explain any advantage of anonymous function, there are some situations where we can utilize them efficiently to simplify the code. I will come to that later.
In practice closures are little more than lambdas. A closure is similar to an anonymous function which can attach a variable to it by using the ‘use’ keyword. Theoretically speaking a closure is a function that wraps the current scope and can have one or more variables attached to it.In order to understand closures you should have a clear idea on scope of a variable in PHP. Since the notion of scope in PHP id little bit different from other languages, this is not so straight forward. Lets take a look in to a javasctipt function that will return the factorial of any given number.
Now let’s language cast this code to php.
Everything will be almost clear from the above example. Using this great math class we can set a multiplier during instantiation and find its product with any number. Note that inside the closure we have assigned $this to $self, because closures don’t support $this variable. In PHP closures are internally managed by a closure class. Closures are an object of closure class. When we call them we are actually invoking an object as if it is a function. PHP 5.3 introduced a new functionality, ‘__invoke()’ method which enabled us to call an object as a function. If $this variable is allowed inside the closure, it will be applied in the context of closure object itself.
Lambdas are a special case of closure and lambda functions created this way are also returning an object of type closure, even though they don’t make use of any property of closures.
Difference between closure and other objects in PHP is, if an object is data and methods that applied on that data, closure is a function with data bound with that function.
We can use closures for prototyping our application. By defining a simple class and dynamically creating the functions we needed we can demonstrate the functionality of the system. For Example
Here we have created a method for that class on the fly. Like that we can create any number of functions, just to demonstrate the functionality.
Implementing callback functions
Another use of closure is in implementing callback functions. Consider an array function ‘array_filter()’ which will take two parameters, first one is the array and second argument is a callback function which will be called against each element in that array. Here we will write the callback function itself as the second argument.
This can be used in implementing modular system with least coupling between the components. There also we may need to implement some callback functions whenever a particular event occurs. (Think about hooks in drupal or actions and filters in wordpress, which will be called on occurring particular events).
Factorial function using lambda function
For finding the factorial of a number using lambda function we will make use of a Y-combinator which is a brain twisting function that will convert any non recursive function to a recursive one. It is written by Stanislav Malyshev in his article Y-Combinator in PHP. It is interesting that Y-combinator has a strong relation with lambda calculus.
The closure way of same factorial function is given below, which is well simplified.
Eli White, in his article, ‘An intriguing use of lambda functions’ describes a specific use of closures.
Since closures are anonymous, they do not appear in reflection. However, a new method was added to the ReflectionMethod and ReflectionFunction classes: getClosure. This method returns a dynamically created closure for the specified function. We can check if a function is closure or not by using isClosure method. For more about this please refer Here.
For an introduction to Reflection api You can refer my previous article
Php version 5.3.4 has fixed some bugs related to closures
Converting closure to array yields empty array
Memory leak when passing a closure to method_exists()
ReflectionClass fails on Closure class
Sometimes we will need to write a function which will be used only once. Lambda functions allow the quick definition of such throw away functions.Even though closures dont bring any thing new to PHP they can help us in managing our code by simplifying it. In future we can expect a new, different programming style in PHP which will make use of this closures and lambda functions extensively.
On PHP 5.3, Lambda Functions, and Closures
Expert PHP and MySQL