Saya memeriksa beberapa PHP 5.3.0
fitur dan menemukan beberapa kode di situs yang terlihat cukup lucu:
public function getTotal($tax)
{
$total = 0.00;
$callback =
/* This line here: */
function ($quantity, $product) use ($tax, &$total)
{
$pricePerItem = constant(__CLASS__ . "::PRICE_" .
strtoupper($product));
$total += ($pricePerItem * $quantity) * ($tax + 1.0);
};
array_walk($this->products, $callback);
return round($total, 2);
}
sebagai salah satu contoh pada fungsi anonim .
Adakah yang tahu tentang ini? Dokumentasi apa saja? Dan itu terlihat jahat, haruskah itu digunakan?
use
kunci juga digunakan untuk alias ruang nama . Sungguh menakjubkan bahwa, lebih dari 3 tahun setelah rilis PHP 5.3.0, sintaksinyafunction ... use
masih resmi tidak berdokumen, yang membuat penutupan menjadi fitur yang tidak berdokumen. Dokumen itu bahkan membingungkan fungsi dan penutupan anonim . Satu-satunya dokumentasi (beta dan tidak resmi) yanguse ()
dapat saya temukan di php.net adalah RFC untuk penutupan .use
juga digunakan untuk memasukkantrait
aclass
!Jawaban yang lebih sederhana.
function ($quantity) use ($tax, &$total) { .. };
$tax
di dalam penutupan tidak memiliki efek eksternal, kecuali itu adalah pointer, seperti objek.&$total
. Dengan cara ini, memodifikasi nilai$total
DOES MEMILIKI efek eksternal, nilai variabel asli berubah.Seperti yang ditunjukkan @Mytskine, mungkin penjelasan terbaik terbaik adalah RFC untuk penutupan . (Beri dia dukungan untuk ini.)
sumber
$closure = function ($value) use ($localVar as $alias) { //stuff};
Kesalahan yang diberikan adalah:Parse: syntax error, unexpected 'as' (T_AS), expecting ',' or ')'
&$total
memiliki efek internal juga. Dengan kata lain, jika Anda mengubah nilai di$total
luar penutupan setelah ditentukan, nilai baru hanya akan diteruskan jika itu adalah pointer.global
hanya memungkinkan akses ke namespace global sedangkanuse
memungkinkan mengakses variabel di namespace induk. Variabel global umumnya dianggap jahat. Mengakses ruang lingkup orang tua sering kali merupakan tujuan dari membuat penutupan. Ini bukan "jahat" karena cakupannya sangat terbatas. Bahasa lain seperti JS secara implisit menggunakan variabel lingkup induknya (sebagai penunjuk, bukan sebagai nilai yang disalin).You can pass in variables as pointers like in case of &$total. This way, modifying the value of $total DOES HAVE an external effect, the original variable's value changes.
Itu
function () use () {}
seperti penutupan untuk PHP.Tanpa
use
, fungsi tidak dapat mengakses variabel lingkup indukNilai
use
variabel berasal dari saat fungsi didefinisikan, bukan saat dipanggiluse
referensi-variabel dengan&
sumber
Penutupan itu indah! mereka memecahkan banyak masalah yang datang dengan fungsi anonim, dan membuat kode yang sangat elegan mungkin (setidaknya selama kita berbicara tentang php).
programmer javascript menggunakan closure sepanjang waktu, kadang-kadang bahkan tanpa menyadarinya, karena variabel terikat tidak didefinisikan secara eksplisit - itulah gunanya "digunakan" untuk di php.
ada contoh dunia nyata yang lebih baik daripada yang di atas. katakanlah Anda harus mengurutkan array multidimensi berdasarkan sub-nilai, tetapi kuncinya berubah.
peringatan: kode yang belum diuji (saya tidak memasang atm php5.3), tetapi seharusnya terlihat seperti itu.
ada satu kelemahan: banyak pengembang php mungkin sedikit tidak berdaya jika Anda menghadapi mereka dengan penutupan.
untuk memahami lebih banyak tentang penutupan, saya akan memberikan Anda contoh lain - kali ini dalam javascript. salah satu masalah adalah pelingkupan dan asinkronitas browser yang melekat. khususnya, jika menyangkut
window.setTimeout();
(atau -interval). jadi, Anda meneruskan fungsi ke setTimeout, tetapi Anda tidak dapat benar-benar memberikan parameter apa pun, karena memberikan parameter mengeksekusi kode!myFunction mengembalikan fungsi dengan parameter yang sudah ditentukan sebelumnya!
jujur, saya lebih suka php lebih dari 5.3 dan fungsi / penutupan anonim. ruang nama mungkin lebih penting, tetapi mereka jauh kurang seksi .
sumber
Zupa melakukan pekerjaan yang bagus menjelaskan penutupan dengan 'penggunaan' dan perbedaan antara EarlyBinding dan Referensi variabel yang 'digunakan'.
Jadi saya membuat contoh kode dengan pengikatan awal variabel (= menyalin):
Contoh dengan mereferensikan variabel (perhatikan karakter '&' sebelum variabel);
sumber
Sampai beberapa tahun terakhir, PHP telah mendefinisikan AST dan interpreter PHPnya telah mengisolasi parser dari bagian evaluasi. Selama waktu penutupan diperkenalkan, parser PHP sangat digabungkan dengan evaluasi.
Oleh karena itu ketika penutupan pertama kali diperkenalkan ke PHP, penerjemah tidak memiliki metode untuk mengetahui variabel mana yang akan digunakan dalam penutupan, karena belum diurai. Jadi pengguna harus menyenangkan mesin zend dengan impor eksplisit, melakukan pekerjaan rumah yang harus dilakukan zend.
Inilah yang disebut cara sederhana dalam PHP.
sumber