
PHP started supporting closure from the 5.3.0 version, but many PHP programmers still don’t know/make effective use of it. I haven’t seen that many articles on it either. In today’s PHP closure tutorial, I will try to cover how you can start using it easily and make your web application more robust/optimized. Before driving into real examples, assuming that you are pretty new to this term, let’s know a few related definitions first:
Anonymous Function: Anonymous function is what its title implies: a function without a name. If you have worked with JavaScript, you should already know such functions. These are useful for writing short inline functions, defining callbacks, etc. A code example of a PHP anonymous function:
$functionReference = function(){
echo "anonymous function called";
};
$functionReference();
//prints: "anonymous function called"
Code language: PHP (php)
You can read more details about the PHP anonymous function in the official documentation.
Lazy Loading: Lazy loading is a common design pattern that indicates deferring the loading of an object until it is required. Why did I use this term in this article? Our closure/anonymous function will help us achieve this feature, that’s why. You will get a clearer picture; just read on.
What is Closure:
Well, closure is nothing but an object representation of an anonymous function. It is the object-oriented way to use an anonymous function. More interestingly, the above anonymous function example returns a reference to the Closure object, not only a function reference. Thus, the PHP closure method ‘bindTo’ can be applied to this reference. The other ‘bind’ method is a static and an alternate way to get the same behaviour.
It’s pretty simple stuff, right? I am not giving any examples here, as you will already see them in different use cases.
What We Can Do With Closure?
Here, I will describe two simple yet powerful features that PHP closure offers us to use:
- accessing private data of an object instance and
- lazy loading
Access Private variable using a closure:
A simple example below will show you one of the superpowers of closure, accessing the private variable of an object:
class SimpleClass {
private $privateData = 2;
}
$simpleClosure = function() {
return $this->privateData;
};
$resultClosure = Closure::bind($simpleClosure, new SimpleClass(), 'SimpleClass');
echo $resultClosure();
Code language: PHP (php)
See? So, if we know the variable name, it’s an excellent way to use private data without modifying the existing class. In the same way, we can add/inject new behaviour to a PHP class without modifying it as well.
Lazy Loading With PHP Closure:
As we have seen in the definition, lazy loading will help prevent any initialization until it’s used. Let’s see an example of how we can achieve this. We will define a Monolog debug logger, which will only be used in some instances.
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
$logClosure = function() {
$log = new Logger('event');
$log->pushHandler(new StreamHandler("logfile.log", Logger::DEBUG));
return $log;
};
//logger will not be initialized until this point
$logger = $logClosure();
Code language: PHP (php)
As you can see here, we can write all definitions without actual initialization using a closure. Later, when needed, we can use it with a simple assignment: ‘$logger = $logClosure()’.
Using External Variable inside closure:
The closure body can only be executed on demand, so passing some external value/variable is slightly different. It would be best to use a new ‘using’ keyword on the PHP closure function definition. Let’s see another example:
$someValue = "sample external data";
$simpleClosure = function() use($someValue) {
return "Test accessing external value inside closure ".$someValue;
};
echo $simpleClosure();
Code language: PHP (php)
What’s Next?
PHP Closure implementation is frequently used in modern applications/frameworks. So, why not you? Give it a try. Happy Coding!
Discover more from CODESAMPLEZ.COM
Subscribe to get the latest posts sent to your email.
I found this article very useful. I wasn’t aware of Lazy Loading or how it effected efficiency.
Jamie @ http://www.redoma.digital
Your first function example uses `echo` two times. You do not need to “echo $functionReference()” – you’d just need to call “$functionReference()” since the echo is already in the function
thanks, updated
How would I define a function that takes a closure as a parameter? For example, imagine if PHP’s ‘array_filter’ didn’t exist…. how would you write that function?