Funkcja anonimowa, nazywana też domknięciem (closure), to funkcja bez nazwy. Piszesz function ($param) { ... } tam, gdzie oczekiwana jest wartość: przypisujesz ją do zmiennej, przekazujesz do innej funkcji albo zwracasz. Może przenosić zmienne z otaczającego kodu przez use ($var).
Każda funkcja anonimowa jest obiektem wbudowanej klasy Closure, dlatego można ją zapisać, przekazywać i wywołać później przez $greet(...).
Słowo kluczowe use przechwytuje przez wartość
Domknięcie samo nie widzi zmiennych z zewnątrz. use ($x) kopiuje wartość $x do domknięcia w chwili jego utworzenia, a nie wtedy, gdy się wykonuje:
use przez referencję: &$var
use (&$x) daje domknięciu samą zmienną, a nie kopię. Zmiany wewnątrz domknięcia są widoczne na zewnątrz, a zmiany na zewnątrz są widoczne wewnątrz. Tak callback dodaje do sumy albo prowadzi licznik.
Każde wywołanie makeCounter() tworzy nowe $count, a zwrócone domknięcie utrzymuje je przy życiu po zakończeniu funkcji. Właśnie do tego odnosi się nazwa „domknięcie”: funkcja domyka się nad zmiennymi, których potrzebuje.
Domknięcie jako callback
Funkcje takie jak array_map(), array_filter(), usort() i array_walk() przyjmują funkcję jako argument. Domknięcie pozwala napisać ją w miejscu, z tyloma instrukcjami, ile wymaga zadanie:
Gdy treść to jedno wyrażenie, funkcja strzałkowa, taka jak fn($p) => $p['price'], jest krótsza i nie potrzebuje use.
Callable: nazwy funkcji, metody i strlen(...)
Parametr z typem callable przyjmuje więcej niż domknięcia. Liczy się string z nazwą funkcji, tablica z obiektem i nazwą metody oraz tablica z nazwą klasy i nazwą metody statycznej. Od PHP 8.1 składnia first-class callable strlen(...) zamienia każde z nich bezpośrednio w Closure.
Forma (...) jest sprawdzana w chwili wykonania linii: literówka od razu rzuca Error. String taki jak 'strtoupr' jest tylko stringiem, dopóki ktoś nie spróbuje go wywołać.
Domknięcia w klasie: $this i static
Domknięcie utworzone wewnątrz metody ma automatycznie powiązane $this, więc może używać właściwości obiektu. Oznacz je jako static function, gdy nie potrzebuje $this; dzięki temu nie utrzymuje też obiektu przy życiu.
Zapomniane use
Najczęstszy błąd z domknięciami to użycie zmiennej z zewnątrz bez wymienienia jej w use. Wewnątrz domknięcia ta zmienna nie istnieje:
$minAge = 18;
$adults = array_filter($people, function ($p) {
return $p['age'] >= $minAge; // $minAge is not in use (...)
});
PHP prints: Warning: Undefined variable $minAge
$minAge ma w środku wartość null, każdy wiek porównany przez >= null daje true i każda osoba przechodzi przez filtr. Na serwerze ukrywającym ostrzeżenia nic ci o tym nie powie. Dodaj zmienną do use:
Najczęściej zadawane pytania
Czym jest domknięcie (closure) w PHP?
Funkcją bez nazwy, utworzoną przez function (...) { ... } i zapisaną w zmiennej albo przekazaną jako argument. PHP reprezentuje ją jako obiekt klasy Closure. Może przenosić zmienne z zasięgu, w którym powstała, wymienione w use (...).
Co robi słowo kluczowe use w domknięciu PHP?
use ($x) kopiuje zmienną z zewnątrz $x do domknięcia w chwili jego utworzenia. Późniejsze zmiany $x na zewnątrz nie są widoczne. Napisz use (&$x), aby zamiast tego współdzielić zmienną, tak by zmiany działały w obie strony.
Czym jest callable w PHP?
Wszystkim, co PHP potrafi wywołać: domknięciem, nazwą funkcji jako stringiem ('strtoupper'), tablicą [$object, 'method'] lub [ClassName::class, 'staticMethod'] albo obiektem z __invoke(). Użyj typu callable, aby przyjąć dowolne z nich, i is_callable(), aby to sprawdzić.
Co oznacza strlen(...) w PHP?
To składnia first-class callable z PHP 8.1: strlen(...) tworzy Closure z funkcji, nie wywołując jej. Działa też dla metod, $obj->method(...), i metod statycznych, Foo::bar(...), i w przeciwieństwie do nazwy w stringu jest sprawdzana w chwili wykonania linii.
Czy po funkcji anonimowej potrzebny jest średnik?
Tak, gdy ją przypisujesz: $f = function () { ... }; to instrukcja przypisania, więc kończy się ;. Pominięcie go to błąd składni. Domknięcie przekazane bezpośrednio jako argument nie potrzebuje własnego średnika.