php闭包中使用use声明变量的作用域实例分析

与此形成鲜明对比的是另一位巨星——葡萄牙队的c罗。上赛季他虽说有42个进球,但经统计,他的效率不到10%。在这个习惯统计学的社会,c罗的42球从深层分析充满了水分。此外,他的球场道德也属于低劣派,假摔贯穿全场,无处不在,江湖人送外号 "跳水运动员 ",桃色风波更是五花八门,而两者后果呢?看看吧:梅西凭借着08—09赛季带领巴萨取得西甲、国王杯、欧洲冠军联赛三冠王,取得433分,获得金球奖,而c罗只有他的一半不到!

本文实例讲述了php闭包中使用use声明变量的作用域。分享给大家供大家参考,具体如下:

<?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中完成)。

希望本文所述对大家PHP程序设计有所帮助。

到此这篇关于php闭包中使用use声明变量的作用域实例分析就介绍到这了。当你感到悲哀痛苦时,最好是去学些什么东西。学习会使你永远立于不败之地。更多相关php闭包中使用use声明变量的作用域实例分析内容请查看相关栏目,小编编辑不易,再次感谢大家的支持!

您可能有感兴趣的文章
php操作zip在不解压缩包的情况下显示压缩包中的图片

PHP性能优化案例分享

PHP实现短信验证码的发送次数限制

PHP中的异常处理机制深入讲解

PHP常见七种算法合集代码实例