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