Penggunaan fungsi CLOSUER pada PHP

Memahami Konsep Closure di PHP/Javascript

Closure! Hmm, topik ini merupakan salah satu topik yang membingungkan buat saya waktu itu (selain Prototyping). Bahkan di beberapa screencast atau video tutorial yang saya lihat, Closure merupakan the weirdest issue atau very missunderstood issue karena konsep dari Javascript yang menggunakan pendekatan event driven environment.

Penggunaan fungsi CLOSUER pada PHP
Gambar 1. Kiri PHP, kanan Javascript.

Coba lihat kedua kode program di atas. Di sebelah kiri saya menggunakan PHP dan sebelah kanan menggunakan Javascript. Kedua program di atas terlihat akan menghasilkan output yang sama, "Hello World!". Benar?

Mari kita eksekusi kode Javascript terlebih dahulu.

Penggunaan fungsi CLOSUER pada PHP
Gambar 4. Hasil output Javascript.

Oke, seperti yang kita duga kode program akan menghasilkan output "Hello World!". Lalu selanjutnya kita eksekusi kode PHP.

Penggunaan fungsi CLOSUER pada PHP
Gambar 3. Hasil output PHP.

Kode program yang kita buat menghasilkan pesan error, "Undefined variable: a". Tunggu, perasaan saya telah mendefinisikan variabel $a = "Hello" di line 5. Apa yang salah?

Di dunia pemrograman kita mengenal istilah scope atau cakupan/ruang lingkup. Variabel $a hanya berada pada ruang lingkup dari fungsi hello() sehingga variabel $a tidak bisa diakses di luar fungsi tersebut. Lalu bagimana dengan variabel $b? Variabel tersebut satu ruang lingkup dengan variabel $a. Tapi kenapa variabel $a tidak bisa diakses oleh variabel $b? Jawabannya karena kita membuatnya menggunakan bahasa pemrograman PHP = Pemberi Harapan Palsu. Hahaha.

Bukan, bukan itu masalahnya. Masalahnya adalah variabel $b berisi Closure. Closure tak lebih dan tak kurang hanyalah sebuah anonymous function. Dan setiap function mempunyai scope-nya sendiri-sendiri. Ingat!

Biar saya ilustrasikan begini. Kita buat saja ilustrasi ini layaknya sebuah percakapan antara saya dengan si PHP. Mari kita mulai!

S: Saya, P: PHP

Penggunaan fungsi CLOSUER pada PHP
Gambar 4. Kode program PHP.

S: Cuy, tolong definisikan fungsi hello dong di line 3.
P: Siap bos. Isi dari fungsinya apa aja bos?
S: Di line 5 ada variabel $a yang isinya "Hello".
P: Oke bos. Udah saya simpan di memori variabel $a yang isinya string "Hello". Ada lagi gak bos?
S: Di line 7 juga tuh, tolong simpan variabel $b yang isinya anonymous function/closure. Di dalamnya jangan lupa dikasih return nilai variabel $a lalu digabung dengan string "World!".
P: Hmm... bos! (si PHP tiba-tibe menyela)
S: Kenapa cuy?
P: Saya mau nge-return variabel $a. Tapi variabel $a yang mana ya bos?
S: Hmmm, dasar PHP bodoh. Masih nanya juga variabel $a yang mana?
P: Iya bos. Saya gak pernah ngerasa si bos nyuruh nyimpen variabel $a di dalam scope ini.
S: Ya tapi kamunya yang harus peka dong jadi bahasa pemrograman!
P: Itu ada sih bos variabel $a yang isinya "Hello" di memori. Tapi yang bos maksud emang variabel $a yang itu bos?
S: Serah lo dah...
P: Oke bos! (alhasil si PHP mengeluarkan pesan error karena menurut si PHP, lebih baik mengeluarkan pesan error daripada salah mengambil nilai dari variabel yang belum tentu benar adanya).

Kira-kira begitulah percakapan yang terjadi antara saya dengan si bodoh PHP. Lalu bagaimana dengan si Javascript? Kira-kira begini percakapan yang berhasil saya rekam.

S: Saya, J: Javascript

Penggunaan fungsi CLOSUER pada PHP
Gambar 5. Kode program Javascript.

P: Cuy, tolong di line 3 buat fungsi namanya hello dong.
J: Siap komandan. Isi dari fungsinya apa aja ndan?
P: Itu ada variabel a di line 5 yang isinya string "Hello".
J: Oke ndan. Ada lagi gak ndan?
P: Ada variabel b juga tuh di line 7. Isinya anonymous function/closure. Tolong isinya itu return dari variabel a terus di gabung sama string "World!" ya. Bisa?
J: Kecil ndan. Biar saya tebak, variabel a yang komandan maksud sama dengan variabel a yang saya simpan sebelumnya kan? Yang satu scope di atas fungsi/closure ini kan ndan?
P: Ih kok kamu pinter! Bener itu.
J: Iya dong ndan.
P: Yaudah, laksanakan!
J: Siap, udah saya simpan di memori dan udah saya return juga nilainya. Ada lagi ndan?
P: Bagus-bagus. Selanjutnya kamu return aja nilai variabel b di line 11. Abis itu kamu boleh istirahat.
J: Asiikkk, siap ndan! (maka si Javascript mengeluarkan output "Hello World!").

Kalo kita perhatikan dua percakapan di atas. Permasalahan yang muncul itu bukan pada si PHP atau si Javascript-nya. Masalah terbesarnya ada pada saya. Saya kurang memberikan instruksi yang lengkap untuk si PHP. Mungkin karena si PHP tidak se-intuitif si Javascript, PHP hanya mengerjakan apa yang benar-benar saya suruh saja.

Under the hood, Javascript secara otomatis mereferensikan variabel $a pada closure $b dengan cara men-inherits scope parentnya. Jadi ketika saya membuat closure $b, secara otomatis scope dari closure $b adalah scope dari fungsi parentnya yaitu fungsi hello().

Namun beda cerita di PHP dimana kamu harus mereferensikan parameternya secara manual.

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.

Lalu bagaimana cara menyuruh si PHP untuk mereferensikan variabel $a yang berapa di parent scope-nya? Kita binding secara manual menggunakan keyword use.

Penggunaan fungsi CLOSUER pada PHP
Gambar 6. Menggunakan keyword use.

Sekarang ayo kita cek apakah si PHP menjalankan perintah seperti yang sudah saya instruksikan.

Penggunaan fungsi CLOSUER pada PHP
Gambar 7. Output PHP

Hello World! :)