В php замыкания это объекты класса Сlosure, создаются при присвоении функции переменной или передачи анонимной функции, и может замыкать в себе значения переменных.
В отличии от JS, функции в PHP не имеют доступа к значениям переменных из родительской области видимости автоматически, его можно получить через use()
Если при создании замыкания мы наследуем переменные из глобальной области через use(), то значение этих переменных будет хранится в замыкании, и будут соответствовать значениям переменных на момент определения функции, а не на момент её вызова.
$message ='привет';// Наследуем $message$example =function () use ($message) {var_dump($message);};$example(); // "Привет"// Значение унаследованной переменной задано там, где функция определена,// но не там, где вызвана (в отличии от JS)$message ='мир';$example(); // "Привет"
Так же созданное замыкание может хранить в себе значение переменной...
functiongetCounter(){ $count =0;returnfunction () use (&$count){ // наследуем по ссылке $count из родительской области видимостиreturn $count++; };}$counter = getCounter(); // получаем замыкание которое хранит в себе значение переменной $count, которая находится в его "замкнутой" родительской области видимости
var_dump($counter);echo$counter(); // 0echo$counter(); // 1echo$counter(); // 2var_dump($counter);
Замыкания в PHP в ООП (Автоматическое связывание $this)
В ООП, когда мы записываем метод обьекта в функцию (например ), то получаем замыкание, которое хранит контекст и значение $this соответствует объекту из которого мы записывали метод.
Но его можно привязать к другому объекту функцией bindTo();
classPerson {public $name;publicfunction__construct($name){$this->name = $name; }publicfunctiongetName(){return$this->name; }publicfunctionrunClosure($closure){// возвращаем результат функции переданной в качестве аргументаreturn$closure(); }}$gizmo =newPerson('Gizmo','mr.');$freeman =newPerson('Freeman','dr.');// записываем метод getName() в переменную (именно объект Closure с функцией внутри, а не результат функции)$closure = $gizmo->getName(...);// вызывем замыкание внутри объекта $freeman, но оно вернёт "Gizmo" так как само замыкание хранит $this которое ссылается на свой объект, в данном случае $gizmo
echo $freeman->runClosure($closure);// связываем замыкание с объектом $freeman$closure = $closure->bindTo($freeman);// и теперь замыкание выдаст "Freeman"echo $freeman->runClosure($closure);