PHP started supporting closure from the 5.3.0 version, but still, many PHP programmers don’t know/make effective use of it yet. I also haven’t seen that many articles on it as well. 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 be familiar with such functions. These are pretty useful for writing short inline functions, defining callback 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 php anonymous function on official documentation.
Lazy Loading: Lazy loading is a common design pattern which indicates the deferring of the loading of an object until it is required. Why I used this term in this article? Our closure/anonymous function will help us achieve this feature, that’s why. You will get a more clear 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 we just saw 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.
Pretty simple stuff! Right? I am not giving any examples here, as you will see them already 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 just know the variable name, it’s an awesome 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 certain cases.
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)
So, as you can see here, we can write all definitions without actual initialization using a closure. Later, when needed, use it with a simple assignment as ‘$logger = $logClosure()’.
Using External Variable inside closure:
As the closure body only be executed on demand, passing some external value/variable is a little different. You will have to use a new ‘using’ keyword for this on 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.
JBWebServices says
I found this article very useful. I wasn’t aware of Lazy Loading or how it effected efficiency.
Jamie @ http://www.redoma.digital
Samuel Fullman says
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
Md Ali Ahsan Rana says
thanks, updated
Dave says
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?