The Closure class
(PHP 5 >= 5.3.0)
Introduction
Class used to represent anonymous functions.
Anonymous functions, implemented in PHP 5.3, yield objects of this type. This fact used to be considered an implementation detail, but it can now be relied upon. Starting with PHP 5.4, this class has methods that allow further control of the anonymous function after it has been created.
Besides the methods listed here, this class also has an __invoke method. This is for consistency with other classes that implement calling magic, as this method is not used for calling the function.
Table of Contents
- Closure::__construct — Constructor that disallows instantiation
- Closure::bind — Duplicates a closure with a specific bound object and class scope
- Closure::bindTo — Duplicates the closure with a new bound object and class scope
Коментарии
This caused me some confusion a while back when I was still learning what closures were and how to use them, but what is referred to as a closure in PHP isn't the same thing as what they call closures in other languages (E.G. JavaScript).
In JavaScript, a closure can be thought of as a scope, when you define a function, it silently inherits the scope it's defined in, which is called its closure, and it retains that no matter where it's used. It's possible for multiple functions to share the same closure, and they can have access to multiple closures as long as they are within their accessible scope.
In PHP, a closure is a callable class, to which you've bound your parameters manually.
It's a slight distinction but one I feel bears mentioning.
Scope
A closure encapsulates its scope, meaning that it has no access to the scope in which it is defined or executed. It is, however, possible to inherit variables from the parent scope (where the closure is defined) into the closure with the use keyword:
function createGreeter($who) {
return function() use ($who) {
echo "Hello $who";
};
}
$greeter = createGreeter("World");
$greeter(); // Hello World
This inherits the variables by-value, that is, a copy is made available inside the closure using its original name.
font: Zend Certification Study Guide.
Small little trick. You can use a closures in itself via reference.
Example to delete a directory with all subdirectories and files:
<?php
$deleteDirectory = null;
$deleteDirectory = function($path) use (&$deleteDirectory) {
$resource = opendir($path);
while (($item = readdir($resource)) !== false) {
if ($item !== "." && $item !== "..") {
if (is_dir($path . "/" . $item)) {
$deleteDirectory($path . "/" . $item);
} else {
unlink($path . "/" . $item);
}
}
}
closedir($resource);
rmdir($path);
};
$deleteDirectory("path/to/directoy");
?>
compare closures:
<?php
(string) new ReflectionFunction($fn) === (string) new ReflectionFunction($fn2)
?>