Menu

Funkcje anonimowe i domknięcia w PHP: słowo kluczowe use

Funkcja anonimowa (domknięcie, closure) to funkcja bez nazwy zapisana w zmiennej: $greet = function ($name) { return "Hi $name"; };. Poznaj słowo kluczowe use, przechwytywanie przez referencję, callable, składnię first-class callable strlen(...) i domknięcia wewnątrz klas.

Na tej stronie są działające edytory: edytuj, uruchamiaj i od razu zobacz wynik.

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.

Ilustracja języków programowania w Coddy

Ucz się programowania z Coddy

ZACZNIJ