PHP匿名函數和閉包使用的句法與普通函數相同,但匿名函和閉包數其實是偽裝成函數的對象.
匿名函數:就是沒有名稱的函數.匿名函數可以賦值給變量,對象傳遞.不過匿名函數仍是函數,因此可以調用,還可以傳入參數.匿名函數特別適合作為函數或方法的回調.
閉包:是指在創建時封裝周圍狀態的函數.即使閉包所在的環境不存在了,閉包中封裝的狀態依然存在.
注意:理論上講,閉包和匿名函數是不同的概念. 不過,PHP將其視作相同的概念.
匿名函數的語法:
1 $func = function(){ 2 3 };//帶結束符
示例demo:
1 $func = function($param){ 2 echo($param); 3 }; 4 $func('hello world');
實現閉包?
將匿名函數在普通函數中當做參數傳入,也可以被返回.這就實現了一個簡單的閉包.
示例demo:
1 //(示例1):函數里定義一個匿名函數,並且調用它 2 function content(){ 3 $func = function($param){ 4 echo $param; 5 }; 6 $func('hello world'); 7 } 8 content();
1 //(示例2):函數中把匿名函數返回,返回后調用它 2 function content(){ 3 return $func = function($param){ 4 echo $param; 5 }; 6 } 7 $data = content(); 8 $data('hello world');
1 //(示例3):把匿名函數當做參數傳遞,並且調用它 2 function callFunc($func){ 3 $func('hello world'); 4 } 5 $data = function($param){ 6 echo $param; 7 }; 8 callFunc($data);die; 9 10 //直接將匿名函數進行傳遞 11 callFunc(function($param){ 12 echo $param; 13 });
閉包使用use關鍵字 use:連接閉包和外界變量
使用語法:
1 $func = function() use(){ 2 3 };
示例demo:
1 //將外層變量傳進內層匿名函數,並且調用 2 function func($param){ 3 return function() use($param){ 4 echo $param; 5 }; 6 } 7 $content = func('hello world'); 8 $content();
closure類中的bind和bindTo
Closure類
方法說明:
Closure::__construct — 用於禁止實例化的構造函數 Closure::bind — 復制一個閉包,綁定指定的$this對象和類作用域 Closure::bindTo — 復制當前閉包對象,綁定指定的$this對象和類作用域
bindTo():
參數1 :傳類進去,public屬性和方法.只傳第1個參數即可 參數2 :傳類進去,private或protected屬性和方法.就要傳第2個參數.兩種寫法:(1)傳類名,直接字符串 (2)傳類當前對象[第一個參數相同的$obj],bindTo()會自動獲取類名
示例demo:
1 <?php 2 class User{ 3 private $name ; 4 function __construct ( $name ){ 5 $this ->name = $name ; 6 } 7 } 8 9 $func = function () { 10 return "Hello " . $this ->name; 11 }; 12 13 $obj = new User('admin'); 14 15 $dataUser = $func->bindTo($obj,'User'); 16 echo $dataUser();//Hello admin 17 18 $dataObj = $func->bindTo($obj,$obj); 19 echo $dataObj();die;//Hello admin
bind():
參數1($closure) :表示閉包函數 參數2($newthis) :相當於在函數內/外調用的區別,傳類的實例表示在內部調用,NULL相當於在外部調用 參數3($newscope) :相當於類和實例調用的區別,函數的作用域,傳類表示靜態調用方式,內部可以“類名::屬性”的方式使用;實例表示實例調用方式,內部可以“->”
示例demo:
1 <?php 2 /** 3 * 復制一個閉包,綁定指定的$this對象和類作用域. 4 */ 5 class Animal { 6 private static $cat = "cat"; 7 private $dog = "dog"; 8 public $pig = "pig"; 9 } 10 11 /* 12 * 獲取Animal類靜態私有成員屬性 13 */ 14 $cat = static function() { 15 return Animal::$cat; 16 }; 17 18 /* 19 * 獲取Animal實例私有成員屬性 20 */ 21 $dog = function() { 22 return $this->dog; 23 }; 24 25 /* 26 * 獲取Animal實例公有成員屬性 27 */ 28 $pig = function() { 29 return $this->pig; 30 }; 31 32 $bindCat = Closure::bind($cat, null, new Animal());// 給閉包綁定了Animal實例的作用域,但未給閉包綁定$this對象 33 $bindDog = Closure::bind($dog, new Animal(), 'Animal');// 給閉包綁定了Animal類的作用域,同時將Animal實例對象作為$this對象綁定給閉包 34 $bindPig = Closure::bind($pig, new Animal());// 將Animal實例對象作為$this對象綁定給閉包,保留閉包原有作用域 35 echo $bindCat(),'<br>';// 根據綁定規則,允許閉包通過作用域限定操作符獲取Animal類靜態私有成員屬性 36 echo $bindDog(),'<br>';// 根據綁定規則,允許閉包通過綁定的$this對象(Animal實例對象)獲取Animal實例私有成員屬性 37 echo $bindPig(),'<br>';// 根據綁定規則,允許閉包通過綁定的$this對象獲取Animal實例公有成員屬性