最近学习Laravel,顺便研究了闭包函数在php里面的作用,php匿名函数也叫闭包函数,php允许临时创建一个没有指定名称的函数 :function(){......}
<?php
function opreation($a)
{
if($a = 1)
{
return function($e,$d){
return $e-$d;
};
}
else
{
return function($e,$d){
return $e+$d;
};
}
}
$fu = opreation(1);
echo $fu(3,4);
print_r($fu);
?>
print_r的结果:
Closure Object ( [parameter] => Array ( [$e] => [$d] => ) )
PHP中的匿名函数可以动态创建并且保存到变量中, 上面的function opreaion()返回的是一个匿名函数,复制给变量$fu,执行$fu()相当于就是执行了匿名函数。 (return function 只是返回函数本身,并不执行这个函数)。
PHP会自动把 闭包函数转化成类Closure的实例 .看上面的打印结果。
下面是一个闭包函数类似容器的的应用:
<?php
header("Content-Type:text/html;charset=utf-8");
class Di{
private $_factory;
public function set($id,$value){
$this->_factory[$id] = $value;
}
public function get($id){
$value = $this->_factory[$id];
return $value();
}
}
class User{
private $_username;
function __construct($username="") {
$this->_username = $username;
}
function getUserName(){
return $this->_username;
}
}
//从这里开始看
$di = new Di();
$di->set("zhangsan",function(){
return new User('张三');
});
$di->set("lisi",function(){
return new User("李四");
});
echo $di->get("zhangsan")->getUserName();
echo $di->get("lisi")->getUserName();
?>
DI容器用来保存对象实例。set方法注册实例,get获得服务,set并没有实例化,get执行了匿名函数返回了对象。
CLOSURE类的bind方法: 赋值一个闭包,绑定指定的对象和作用域,返回一个新的CLOSURE对象,(新的闭包):
Closure{
__construct(void)
public static Closure bind ( Closure $closure , object $newthis [, mixed $newscope = 'static' ] )
public Closure bindTo ( object $newthis [, mixed $newscope = 'static' ] )
}
Closure::__construct — 用于禁止实例化的构造函数
Closure::bind — 复制一个闭包,绑定指定的$this对象和类作用域。
Closure::bindTo — 复制当前闭包对象,绑定指定的$this对象和类作用域。
Closure::bind
closure 表示需要绑定的闭包对象。
newthis 表示需要绑定到闭包对象的对象,或者NULL创建未绑定的闭包。
newscope 想要绑定给闭包的类作用域,或者 'static' 表示不改变。如果传入一个对象,则使用这个对象的类型名。 类作用域用来决定在闭包中 $this 对象的 私有、保护方法 的可见性。
总结,当访问的闭包$this对象是私有、保护、公有时, newthis 需要传入 需要绑定的对象或者null,当访问的是静态属性或方法时,必须传入null
class A {
public $base = 100;
}
class B {
private $base = 1000;
}
class C {
private static $base = 10000;
}
$f = function () {
return $this->base + 3;
};
$sf = static function() {
return self::$base + 3;
};
$a = Closure::bind($f, new A);
print_r($a);
print_r($a());
echo PHP_EOL;
$b = Closure::bind($f, new B , 'B');
print_r($b());
echo PHP_EOL;
$c = $sf->bindTo(null, 'C');
print_r($c());
echo PHP_EOL;
?>
Closure Object ( [this] => A Object ( [base] => 100 ) ) 103 1003 10003
上述的闭包函数中出现了$this 说明是需要绑定到类中去的。