Fungsi anonim, yang juga disebut closure, adalah fungsi tanpa nama. Kamu menulis function ($param) { ... } di tempat yang membutuhkan sebuah nilai: simpan ke variabel, kirim ke fungsi lain, atau kembalikan sebagai hasil. Fungsi ini bisa membawa variabel dari kode di sekitarnya dengan use ($var).
Setiap fungsi anonim adalah objek dari class bawaan Closure. Karena itulah ia bisa disimpan, dioper ke mana-mana, lalu dipanggil nanti dengan $greet(...).
Kata kunci use menangkap nilai (by value)
Closure tidak bisa melihat variabel di luar dirinya dengan sendirinya. use ($x) menyalin nilai $x ke dalam closure pada saat closure dibuat, bukan saat closure dijalankan:
use lewat referensi: &$var
use (&$x) memberi closure variabel itu sendiri, bukan salinannya. Perubahan di dalam closure terlihat di luar, dan perubahan di luar terlihat di dalam. Dengan cara inilah sebuah callback menambah total atau menyimpan penghitung.
Setiap panggilan ke makeCounter() membuat $count yang baru, dan closure yang dikembalikan menjaga variabel itu tetap hidup setelah fungsinya selesai. Itulah maksud kata "closure": fungsi itu "menutup" variabel yang ia butuhkan.
Mengirim closure sebagai callback
Fungsi seperti array_map(), array_filter(), usort(), dan array_walk() menerima fungsi sebagai argumen. Dengan closure, kamu bisa menulis fungsi itu langsung di tempatnya, dengan pernyataan sebanyak yang dibutuhkan:
Kalau body-nya hanya satu ekspresi, arrow function seperti fn($p) => $p['price'] lebih pendek dan tidak butuh use.
Callable: nama fungsi, method, dan strlen(...)
Parameter bertipe callable menerima lebih dari sekadar closure. String berisi nama fungsi, array berisi objek dan nama method, serta array berisi nama class dan nama static method juga dihitung. Sejak PHP 8.1, sintaks first-class callable strlen(...) langsung mengubah semuanya menjadi Closure.
Bentuk (...) diperiksa saat barisnya berjalan: salah ketik langsung melempar Error di situ. String seperti 'strtoupr' hanyalah string sampai ada yang mencoba memanggilnya.
Closure di dalam class: $this dan static
Closure yang dibuat di dalam method otomatis terikat ke $this, jadi ia bisa memakai property objek. Tandai dengan static function kalau tidak butuh $this; ini juga mencegah closure membuat objeknya tetap hidup.
Lupa menulis use
Bug closure yang paling umum adalah memakai variabel dari luar tanpa mencantumkannya di use. Di dalam closure, variabel itu tidak ada:
$minAge = 18;
$adults = array_filter($people, function ($p) {
return $p['age'] >= $minAge; // $minAge is not in use (...)
});
PHP prints: Warning: Undefined variable $minAge
$minAge bernilai null di dalam closure, usia apa pun yang dibandingkan >= null hasilnya true, dan setiap orang lolos filter. Di server yang menyembunyikan warning, tidak ada yang memberitahumu. Tambahkan variabelnya ke use:
Pertanyaan yang sering diajukan
Apa itu closure di PHP?
Fungsi tanpa nama yang dibuat dengan function (...) { ... } lalu disimpan di variabel atau dikirim sebagai argumen. PHP menyimpannya sebagai objek dari class Closure. Closure bisa membawa variabel dari scope tempat ia dibuat, yang ditulis di use (...).
Apa fungsi kata kunci use pada closure PHP?
use ($x) menyalin variabel luar $x ke dalam closure saat closure dibuat. Perubahan $x di luar setelah itu tidak terlihat. Tulis use (&$x) untuk berbagi variabel yang sama, sehingga perubahan berlaku ke dua arah.
Apa itu callable di PHP?
Apa pun yang bisa dipanggil oleh PHP: closure, nama fungsi berupa string ('strtoupper'), array [$object, 'method'] atau [ClassName::class, 'staticMethod'], atau objek yang punya __invoke(). Pakai tipe callable untuk menerima semuanya dan is_callable() untuk memeriksanya.
Apa arti strlen(...) di PHP?
Itu sintaks first-class callable dari PHP 8.1: strlen(...) membuat Closure dari fungsi tersebut tanpa memanggilnya. Sintaks ini juga bisa dipakai untuk method, $obj->method(...), dan static method, Foo::bar(...), dan langsung diperiksa saat barisnya berjalan, tidak seperti nama berupa string.
Apakah perlu titik koma setelah fungsi anonim?
Perlu, kalau kamu menyimpannya ke variabel: $f = function () { ... }; adalah pernyataan assignment, jadi diakhiri dengan ;. Tanpa titik koma, terjadi parse error. Closure yang langsung dikirim sebagai argumen tidak butuh titik koma sendiri.