php匿名函數和閉包的理解


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類中的bindbindTo
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實例公有成員屬性

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM