Closure类,用于代表匿名函数的类。
http://blog.csdn.net/wuxing26jiayou/article/details/51067190
Closure::__construct — 用于禁止实例化的构造函数
Closure::bind — 复制一个闭包,绑定指定的$this对象和类作用域。
Closure::bindTo — 复制当前闭包对象,绑定指定的$this对象和类作用域
Closure {
/* 方法 */
__construct ( void )
public static Closure bind ( Closure $closure , object $newthis [, mixed $newscope = 'static' ] )
public Closure bindTo ( object $newthis [, mixed $newscope = 'static' ] )
}
$closure:表示需要绑定的闭包对象。
$newthis:表示需要绑定到闭包对象的对象,或者null创建未绑定闭包。
$newscope:表示想要给绑定给闭包的类的作用域,可以传入类名或者类的实例,默认值是static,表示不改变,该方法成功时,返回一个新的Closure对象。失败返回false
(不是很理解,后续再看)
在本质上,闭包是将函数内部和函数外部连接起来的桥梁。php匿名函数就是将函数赋值给一个变量中。
匿名函数可用于动态创建函数,并保存到一个变量中
可以看出匿名函数都是Closure的实例。Closure对象。匿名函数可以存储在变量中,打印该变量可以看出是Closure对象。运行该变量就相当于执行了该匿名函数。
<?php
/*
$closure = function ($data) {
print_r($data);
};
var_dump($closure instanceof Closure);
print_r($closure);
$closure('this is my test');
*/
/**
boolean true
Closure Object ( [parameter] => Array ( [$data] => ) ) this is my test
*/
根据传入不同参数返回不同的匿名函数,存储在不同变量中,动态了创建了减法运算和加法运算函数。
function operate($operator) {
if ($operator == '-') {
return function ($a, $b) {
return $a - $b;
};
} else {
return function ($a, $b) {
return $a + $b;
};
}
}
//返回一个匿名函数
$substraction = operate('-');
//通过该变量可以执行匿名函数
echo $substraction(, );
$add = operate('+');
echo $add(, );
Di容器,用来保存对象实例,然后通过set()方法进行注册服务,通过get()方法获取服务。set()方法参数使用了匿名函数。存储在factory变量中,预先注册进来,注册服务都是User的实例。
di−>set实际上并没有实例化,而是等到 di->get()的时候才执行匿名函数new User()并将对象返回,然后通过该对象我们可以调用相关的方法。
按需实例化,不用则不实例化,提高效率,懒加载方式。
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;
public function __construct($username)
{
$this->_username = $username;
}
public function getUserName() {
return $this->_username;
}
}
$di = new Di();
$di->set('zhangsan', function () {
return new User('张三');
});
/*
print_r($di);
* Di Object ( [_factory:Di:private] => Array ( [zhangsan] => Closure Object ( ) ) )
*/
/**
print_r($di->get('zhangsan'));
* User Object ( [_username:User:private] => 张三 )
*/
print_r($di->get('zhangsan')->getUserName());//张三
父函数里面可以定义子函数,父函数变量在子函数中可以通过use来进行传递使用。
注意:use()里面的变量只能算是外部变量的一个副本,如果要改变外部变量的值,需要改为引用,加上&变量名
function cloDemo($data = '') {
return function ($a, $b) use($data) {
print_r("now sub var is a=".$a." and var b =".$b." and parent data is =".$data);
};
}
$demo = cloDemo('我是张三');
$demo('匿名函数参数a', '匿名函数参数b');
总结
匿名函数可以赋值给一个变量;也可以当做参数进行传递;也可以在普通函数里面使用它(传给一个变量、作为函数返回等)
闭包的代码相对优雅,但是逻辑比较容易混淆,相比其他方式执行效率相对较低,要慎用。建议在代码结构比较乱,需要封装的时候使用。