PHP 閉包我的的簡單理解,就是在匿名函數中經過use直接使用函數以外的變量。閉包
這個函數以外如何定義?函數
例如scala
<? function total(){ $total = 0; $sub = 0; $callback = function($a, $b) use ($total, &$sub){ //$total 即匿名函數以外的變量 //&$sub 即匿名函數以外的引用 $sub = $a+$b+$total; }; $callback(1, 2); return $sub; } ?>
PHP 5.3以後引入了新的閉包語法 即function() use (){}code
function能夠添加參數做爲匿名函數的調用參數對象
use能夠添加參數和引用,這些參數位於匿名函數以外,經過use來使用。string
具體語法以下:io
//定義一個回掉函數 function callback($callback) { $callback(); } //這裏是直接定義一個匿名函數進行傳遞, 在以往的版本中, 這是不可用的. callback(function() { print "This is a anonymous function."; }); //輸出: This is a anonymous function. //這裏首先定義了一個閉包, 此次戶口本上有名字了... //use, 一個新鮮的傢伙... //衆所周知, 閉包: 內部函數使用了外部函數中定義的變量. //在PHP新開放的閉包語法中, 咱們就是用use來使用閉包外部定義的變量的. //這裏咱們使用了外部變量$msg, 定義完以後, 又對其值進行了改變, 閉包被執行後輸出的是原始值 //結論: 以傳值方式傳遞的基礎類型參數, 閉包use的值在閉包建立是就肯定了. $msg = "Hello, everyone"; $callback = function () use ($msg) { print "This is a closure use string value, msg is: $msg. "; }; $msg = "Hello, everybody"; callback($callback); //輸出: This is a closure use string value, msg is: Hello, everyone. //換一種引用方式, 咱們使用引用的方式來use //能夠發現此次輸出是閉包定義後的值... //這個其實不難理解, 咱們以引用方式use, 那閉包use的是$msg這個變量的地址 //當後面對$msg這個地址上的值進行了改變以後, 閉包內再輸出這個地址的值時, 天然改變了. $msg = "Hello, everyone"; $callback = function () use (&$msg) { print "This is a closure use string value lazy bind, msg is: $msg. "; }; $msg = "Hello, everybody"; callback($callback); //輸出: This is a closure use string value lazy bind, msg is: Hello, everybody. //閉包中輸出的是以前被拷貝的值爲Hello, everyone的對象, 後面是對$obj這個名字的一個從新賦值. //能夠這樣考慮 //1. obj是對象Hello, everyone的名字 //2. 對象Hello, everyone被閉包use, 閉包產生了一個對Hello, everyone對象的引用 //3. obj被修改成Hello, everybody這個對象的名字 //4. 注意, 是名字obj表明的實體變了, 而不是Hello, everyone對象, 那天然閉包的輸出仍是前面的Hello, everyone $obj = (object) "Hello, everyone"; $callback = function () use ($obj) { print "This is a closure use object, msg is: {$obj->scalar}. "; }; $obj = (object) "Hello, everybody"; callback($callback); //輸出: This is a closure use object, msg is: Hello, everyone. //仍是按照上面的步驟, 循序漸進的來吧: //1. obj名字指向Hello, everyone對象 //2. 閉包產生一個引用指向Hello, everyone對象 //3. 修改obj名字指向的對象(即Hello, everyone對象)的scalar值 //4. 執行閉包, 輸出的天然是Hello, everybody, 由於其實只有一個真正的對象 $obj = (object) "Hello, everyone"; $callback = function () use ($obj) { print "This is a closure use object, msg is: {$obj->scalar}. "; }; $obj->scalar = "Hello, everybody"; callback($callback); //輸出: This is a closure use object, msg is: Hello, everybody. //閉包引用的是什麼呢? &$obj, 閉包產生的引用指向$obj這個名字所指向的地址. //所以, 不管obj怎麼變化, 都是逃不脫的.... //因此, 輸出的就是改變後的值 $obj = (object) "Hello, everyone"; $callback = function () use (&$obj) { print "This is a closure use object lazy bind, msg is: {$obj->scalar}. "; }; $obj = (object) "Hello, everybody"; callback($callback); //輸出: This is a closure use object lazy bind, msg is: Hello, everybody.