-
<?php
-
function getClosure($i)
-
{
-
$i = $i.'-'.date('H:i:s');
-
return function ($param) use ($i) {
-
echo "--- param: $param ---\n";
-
echo "--- i: $i ---\n";
-
};
-
}
-
-
$c = getClosure(123);
-
$i = 456;
-
$c('test');
-
sleep(3);
-
$c2 = getClosure(123);
-
$c2('test');
-
$c('test');
-
-
-
/*
-
output:
-
--- param: test ---
-
--- i: 123-21:36:52 ---
-
--- param: test ---
-
--- i: 123-21:36:55 ---
-
--- param: test ---
-
--- i: 123-21:36:52 ---
-
*/
如上,闭包中使用use声明的变量来自于生成闭包实例时所在作用域内的同名变量,而不是来自于运行闭包时所在作用域内的同名变量。而闭包的函数参数则是和正常的函数参数一样来自于运行时所在作用域内的同名变量。
以下为opcode:
-
Finding entry points
-
Branch analysis from position: 0
-
Jump found. Position 1 = -2
-
filename: /tmp/testclosure.php
-
function name: (null)
-
number of ops: 20
-
compiled vars: !0 = $c, !1 = $i, !2 = $c2
-
line #* E I O op fetch ext return operands
-
-------------------------------------------------------------------------------------
-
2 0 E > NOP
-
11 1 SEND_VAL 123
-
2 DO_FCALL 1 $0 'getclosure'
-
3 ASSIGN !0, $0
-
12 4 ASSIGN !1, 456
-
13 5 INIT_FCALL_BY_NAME !0
-
6 SEND_VAL 'test'
-
7 DO_FCALL_BY_NAME 1
-
14 8 SEND_VAL 3
-
9 DO_FCALL 1 'sleep'
-
15 10 SEND_VAL 123
-
11 DO_FCALL 1 $5 'getclosure'
-
12 ASSIGN !2, $5
-
16 13 INIT_FCALL_BY_NAME !2
-
14 SEND_VAL 'test'
-
15 DO_FCALL_BY_NAME 1
-
17 16 INIT_FCALL_BY_NAME !0
-
17 SEND_VAL 'test'
-
18 DO_FCALL_BY_NAME 1
-
29 19 > RETURN 1
-
-
Function %00%7Bclosure%7D%2Ftmp%2Ftestclosure.php0x7fb0115f505:
-
Finding entry points
-
Branch analysis from position: 0
-
Jump found. Position 1 = -2
-
filename: /tmp/testclosure.php
-
function name: {closure}
-
number of ops: 12
-
compiled vars: !0 = $param, !1 = $i
-
line #* E I O op fetch ext return operands
-
-------------------------------------------------------------------------------------
-
5 0 E > RECV !0
-
1 FETCH_R static $0 'i'
-
2 ASSIGN !1, $0
-
6 3 ADD_STRING ~2 '---+param%3A+'
-
4 ADD_VAR ~2 ~2, !0
-
5 ADD_STRING ~2 ~2, '+---%0A'
-
6 ECHO ~2
-
7 7 ADD_STRING ~3 '---+i%3A+'
-
8 ADD_VAR ~3 ~3, !1
-
9 ADD_STRING ~3 ~3, '+---%0A'
-
10 ECHO ~3
-
8 11 > RETURN null
-
-
End of function %00%7Bclosure%7D%2Ftmp%2Ftestclosure.php0x7fb0115f505
-
-
Function getclosure:
-
Finding entry points
-
Branch analysis from position: 0
-
Jump found. Position 1 = -2
-
filename: /tmp/testclosure.php
-
function name: getClosure
-
number of ops: 9
-
compiled vars: !0 = $i
-
line #* E I O op fetch ext return operands
-
-------------------------------------------------------------------------------------
-
2 0 E > RECV !0
-
4 1 CONCAT ~0 !0, '-'
-
2 SEND_VAL 'H%3Ai%3As'
-
3 DO_FCALL 1 $1 'date'
-
4 CONCAT ~2 ~0, $1
-
5 ASSIGN !0, ~2
-
5 6 DECLARE_LAMBDA_FUNCTION '%00%7Bclosure%7D%2Ftmp%2Ftestclosure.php0x7fb0115f5051'
-
8 7 > RETURN ~4
-
9 8* > RETURN null
-
-
End of function getclosure
如上,闭包函数的op_array(相当于类定义)在编译期完成,但在运行期生成闭包实例(相当于类实例)时会为不同实例绑定不同的use静态变量(在DECLARE_LAMBDA_FUNCTION中完成)。
阅读(866) | 评论(0) | 转发(0) |