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

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

rush:PHP;"> 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静态变量(在

更多关于PHP相关内容感兴趣的读者可查看本站专题:《》、《》、《》、《》、《》、《》、《》及《

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

相关文章

统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...
统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...
前言 之前做了微信登录,所以总结一下微信授权登录并获取用户...
FastAdmin是我第一个接触的后台管理系统框架。FastAdmin是一...
之前公司需要一个内部的通讯软件,就叫我做一个。通讯软件嘛...
统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...