Learn And Life.

PHP闭包

先看看什么是闭包,闭包也就是所谓的匿名函数,只是函数的一种隐式定义,从结构化的角度可以理解为,有且只有一次调用。匿名函数并不是一个函数,而是Closure类的一个对象,Closure类是一个final类,不可以继承,同时也不可以被实例化,那么如何通过声明一个匿名函数就实现了Closure类的实例化了呢?
以下是php的源码中的部分代码:

1
2
3
4
5
6
7
8
9
10
11
12
ZEND_VM_HANDLER(153, ZEND_DECLARE_LAMBDA_FUNCTION, CONST, UNUSED)
{
...
if (UNEXPECTED((op_array->common.fn_flags & ZEND_ACC_STATIC) ||
(EX(prev_execute_data) &&
EX(prev_execute_data)->function_state.function->common.fn_flags & ZEND_ACC_STATIC))) {
zend_create_closure(&EX_T(opline->result.var).tmp_var, (zend_function *) op_array, EG(called_scope), NULL TSRMLS_CC);
} else {
zend_create_closure(&EX_T(opline->result.var).tmp_var, (zend_function *) op_array, EG(scope), EG(This) TSRMLS_CC);
}
...
}

还是看看闭包怎么用吧!先声明,后调用。先看闭包的几种使用场景。
场景一: 简单函数,分为使用use和不使用use

1
2
3
4
$outer = "welcome.....";
$colsure = function($inner,$outer) use ($outer){
......
}

由此可见,加use和不加use的区别,就是use能处理外部输入的参数,而function后面的括号,能处理内部参数(实现递归)和接受外部输入的参数

场景二: 实现回调

1
2
3
4
5
6
7
8
9
10
11
12
function extractParam($func='')
{
if(empty($func)){
return;
}
return $func();
}
extractParam(function($param){
return $param;
});

场景三: 实现类的注册

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class Binder
{
protected $_binders = [];
public function getClosure($abstract, $concrete)
{
return function ($container, $parameters = []) use ($abstract, $concrete){
$method = ($abstract == $concrete) ? 'build' : 'make';
return $container->$method($concrete, $parameters);
};
}
public function build($abstract,$concrete)
{
$this->_binders[$abstract] = $concrete;
}
public function make($abstract)
{
.......
}
public function getBinders()
{
return $this->_binders;
}
}
class Bind
{
.......
}
$binder = new Binder();
$regitser = $binder->getClosure($abstract, $concrete);
$regitser(new $binder->getBinders())

闭包的使用,可以使代码更加的紧凑,耦合性更低,使对代码的结构看起来更加的美观,至于性能问题,是php内核实现的,预编译的时候生成,所以可以不用担心!