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


Posted in PHP onAugust 09, 2018

本文实例讲述了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 相关文章推荐
PHP 替换模板变量实现步骤
Aug 24 PHP
用php随机生成福彩双色球号码的2种方法
Feb 04 PHP
关于zend studio 出现乱码问题的总结
Jun 23 PHP
关于Sphinx创建全文检索的索引介绍
Jun 25 PHP
php实现上传图片生成缩略图示例
Apr 13 PHP
Linux下PHP加速器APC的安装与配置笔记
Oct 24 PHP
PHP中的表达式简述
May 29 PHP
PHP反射机制原理与用法详解
Feb 15 PHP
PHP正则删除HTML代码中宽高样式的方法
Jun 12 PHP
php魔法函数与魔法常量使用介绍
Jul 23 PHP
PHP+fiddler抓包采集微信文章阅读数点赞数的思路详解
Dec 20 PHP
php微信小程序解包过程实例详解
Mar 31 PHP
php生成二维码不保存服务器还有下载功能的实现代码
Aug 09 #PHP
PHP命令Command模式用法实例分析
Aug 08 #PHP
PHP耦合设计模式实例分析
Aug 08 #PHP
thinkPHP框架整合tcpdf插件操作示例
Aug 07 #PHP
php实现往pdf中加数字签名操作示例【附源码下载】
Aug 07 #PHP
php使用环形链表解决约瑟夫问题完整示例
Aug 07 #PHP
postman的安装与使用方法(模拟Get和Post请求)
Aug 06 #PHP
You might like
php实现的百度搜索某地天气的小偷代码
2014/04/23 PHP
php创建、获取cookie及基础要点分析
2015/01/26 PHP
用JAVASCRIPT如何给&amp;lt;textarea&amp;gt;&amp;lt;/textarea&amp;gt;赋值
2007/04/20 Javascript
javascript 跳转代码集合
2009/12/03 Javascript
JavaScript this调用规则说明
2010/03/08 Javascript
jQuery 选择器、DOM操作、事件、动画
2010/11/25 Javascript
jquery 获取表单元素里面的值示例代码
2013/07/28 Javascript
输入自动提示搜索提示功能的使用说明:sugggestion.txt
2013/09/02 Javascript
修改或扩展jQuery原生方法的代码实例
2015/01/13 Javascript
javascript中数组的定义及使用实例
2015/01/21 Javascript
javascript中的正则表达式使用指南
2015/03/01 Javascript
javascript引用类型指针的工作方式
2015/04/13 Javascript
使用javascript插入样式
2016/03/14 Javascript
Jquery ui datepicker设置日期范围,如只能隔3天【实现代码】
2016/05/04 Javascript
JSONP跨域请求
2017/03/02 Javascript
解决vue路由name同名,路由重复的问题
2020/08/05 Javascript
Javascript var变量删除原理及实现
2020/08/26 Javascript
javascript操作向表格中动态加载数据
2020/08/27 Javascript
python中redis的安装和使用
2016/12/04 Python
python一键升级所有pip package的方法
2017/01/16 Python
Python中最大最小赋值小技巧(分享)
2017/12/23 Python
Python编程实现的简单神经网络算法示例
2018/01/26 Python
Python中*args和**kwargs的区别详解
2019/09/17 Python
PyTorch 普通卷积和空洞卷积实例
2020/01/07 Python
Python3操作MongoDB增册改查等方法详解
2020/02/10 Python
使用OpenCV获取图像某点的颜色值,并设置某点的颜色
2020/06/02 Python
推荐一些比较有用的css3新属性
2014/11/11 HTML / CSS
意大利独特而优质的家居用品:Fazzini
2018/12/05 全球购物
俄罗斯EPL钻石珠宝店:ЭПЛ
2019/10/22 全球购物
营销总经理的岗位职责
2013/12/15 职场文书
给导游的表扬信
2014/01/10 职场文书
投资意向书
2014/07/30 职场文书
护士优质服务演讲稿
2014/08/26 职场文书
群众路线查摆问题整改措施
2014/10/10 职场文书
七年级作文之游记
2019/12/11 职场文书
Python使用海龟绘图实现贪吃蛇游戏
2021/06/18 Python