Класс Closure

(PHP 5 >= 5.3.0, PHP 7, PHP 8)

Π’Π²Π΅Π΄Π΅Π½ΠΈΠ΅

Класс прСдставляСт Π°Π½ΠΎΠ½ΠΈΠΌΠ½Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ.

АнонимныС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ становятся ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌΠΈ Closure. Класс содСрТит ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ для управлСния экзСмпляром Π°Π½ΠΎΠ½ΠΈΠΌΠ½ΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ.

ΠšΡ€ΠΎΠΌΠ΅ списка ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² Π½Π° этой страницС, класс замыкания Ρ‚Π°ΠΊΠΆΠ΅ содСрТит магичСский ΠΌΠ΅Ρ‚ΠΎΠ΄ __invoke, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΠ»ΠΈ Π½Π΅ для Π²Ρ‹Π·ΠΎΠ²Π° Π°Π½ΠΎΠ½ΠΈΠΌΠ½ΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ β€” ΠΌΠ΅Ρ‚ΠΎΠ΄ Π½Π΅ срабатываСт ΠΏΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° замыкания, β€” Π° Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для согласованности с Π΄Ρ€ΡƒΠ³ΠΈΠΌΠΈ классами, Π² ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π»ΠΈ магичСский Π²Ρ‹Π·ΠΎΠ² ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΊΠ°ΠΊ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ.

ΠžΠ±Π·ΠΎΡ€ класса

final class Closure {
/* ΠœΠ΅Ρ‚ΠΎΠ΄Ρ‹ */
private function __construct()
public static function bind(Closure $closure, ?object $newThis, object|string|null $newScope = "static"): ?Closure
public function bindTo(?object $newThis, object|string|null $newScope = "static"): ?Closure
public function call(object $newThis, mixed ...$args): mixed
public static function fromCallable(callable $callback): Closure
public static function getCurrent(): Closure
}

Бписок измСнСний

ВСрсия ОписаниС
8.4.0 Π’Ρ‹Π²ΠΎΠ΄ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° Closure::__debugInfo() Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Π²ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ свойства ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° замыкания: "name", "line" ΠΈ "file".

ΠŸΡ€ΠΈΠΌΠ΅Ρ‡Π°Π½ΠΈΡ

Π—Π°ΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅: ΠžΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ Closure Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ ΡΠ΅Ρ€ΠΈΠ°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ замыкания ΡΠ²ΡΠ·Ρ‹Π²Π°ΡŽΡ‚ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ Π² ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠΌ контСкстС выполнСния, Π΄ΠΎΡΡ‚ΡƒΠΏΠ½ΠΎΡΡ‚ΡŒ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π² Ρ‚ΠΎΡ‡ΠΊΠ΅ восстановлСния, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΏΡ€ΠΈ дСсСриализации замыкания Π² Π΄Ρ€ΡƒΠ³ΠΎΠΉ области дСйствия. ΠŸΠΎΠΏΡ‹Ρ‚ΠΊΠ° ΡΠ΅Ρ€ΠΈΠ°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π·Π°ΠΌΡ‹ΠΊΠ°Π½ΠΈΠ΅ выбросит ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ Exception.

Π‘ΠΎΠ΄Π΅Ρ€ΠΆΠ°Π½ΠΈΠ΅

  • Closure::__construct β€” ΠšΠΎΠ½ΡΡ‚Ρ€ΡƒΠΊΡ‚ΠΎΡ€, Π·Π°ΠΏΡ€Π΅Ρ‰Π°ΡŽΡ‰ΠΈΠΉ созданиС экзСмпляра
  • Closure::bind β€” Π”ΡƒΠ±Π»ΠΈΡ€ΡƒΠ΅Ρ‚ Π·Π°ΠΌΡ‹ΠΊΠ°Π½ΠΈΠ΅ ΠΈ привязываСт копию замыкания ΠΊ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρƒ ΠΈ области видимости класса статичСски
  • Closure::bindTo β€” Π”ΡƒΠ±Π»ΠΈΡ€ΡƒΠ΅Ρ‚ Π·Π°ΠΌΡ‹ΠΊΠ°Π½ΠΈΠ΅ ΠΈ привязываСт копию замыкания ΠΊ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρƒ ΠΈ области видимости класса
  • Closure::call β€” БвязываСт ΠΈ запускаСт Π·Π°ΠΌΡ‹ΠΊΠ°Π½ΠΈΠ΅
  • Closure::fromCallable β€” ΠšΠΎΠ½Π²Π΅Ρ€Ρ‚ΠΈΡ€ΡƒΠ΅Ρ‚ callable Π² Π·Π°ΠΌΡ‹ΠΊΠ°Π½ΠΈΠ΅
  • Closure::getCurrent β€” Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π΅ выполняСмоС Π·Π°ΠΌΡ‹ΠΊΠ°Π½ΠΈΠ΅
οΌ‹Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ

ΠŸΡ€ΠΈΠΌΠ΅Ρ‡Π°Π½ΠΈΡ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ 4 notes

up
478
chuck at bajax dot us ΒΆ
11 years ago
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.
up
113
joe dot scylla at gmail dot com ΒΆ
10 years ago
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");
?>
up
75
luk4z_7 at hotmail dot com ΒΆ
10 years ago
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.
up
4
info at ensostudio dot ru ΒΆ
4 years ago
compare closures:
<?php 
(string) new ReflectionFunction($fn) === (string) new ReflectionFunction($fn2)
?>