匿名函数和闭包案例分析

作者:echo曦 来源:www.cnblogs.com 更新时间:2023-05-25 21:55

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实例公有成员属性