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 相关文章推荐
ExtJS与PHP、MySQL实现存储的方法
Apr 02 PHP
php批量更改数据库表前缀实现方法
Oct 26 PHP
浅谈php函数serialize()与unserialize()的使用方法
Aug 19 PHP
PHP 反射(Reflection)使用实例
May 12 PHP
thinkphp微信开发(消息加密解密)
Dec 02 PHP
详解WordPress中提醒安装插件以及隐藏插件的功能实现
Dec 25 PHP
简单了解将WordPress中的工具栏移到底部的小技巧
Dec 31 PHP
详解PHP数据压缩、加解密(pack, unpack)
Dec 17 PHP
PHP使用mysqli操作MySQL数据库的简单方法
Feb 04 PHP
laravel框架数据库配置及操作数据库示例
Oct 10 PHP
PHP中用Trait封装单例模式的实现
Dec 18 PHP
PHP pthreads v3下worker和pool的使用方法示例
Feb 21 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/05/28 PHP
php获得文件夹下所有文件的递归算法的简单实例
2016/11/01 PHP
通过JS 获取Mouse Position(鼠标坐标)的代码
2009/09/21 Javascript
jQuery之浮动窗口实现代码(两种方法)
2010/09/08 Javascript
jQuery 开发者应该注意的9个错误
2012/05/03 Javascript
文本框input聚焦失焦样式实现代码
2012/10/12 Javascript
javascript操作html控件实例(javascript添加html)
2013/12/02 Javascript
js设置cookie过期当前时间减去一秒相当于立即过期
2014/09/04 Javascript
ajax跨域调用webservice的实现代码
2016/05/09 Javascript
BootStrap Table后台分页时前台删除最后一页所有数据refresh刷新后无数据问题
2016/12/28 Javascript
纯JS实现弹性导航条效果
2017/03/06 Javascript
JQuery中Ajax的操作完整例子
2017/03/07 Javascript
使用vue-resource进行数据交互的实例
2017/09/02 Javascript
javascript实现循环广告条效果
2017/12/12 Javascript
webpack组织模块打包Library的原理及实现
2018/03/10 Javascript
vue配置请求本地json数据的方法
2018/04/11 Javascript
JS使用Chrome浏览器实现调试线上代码
2020/07/23 Javascript
jQuery实现简单评论功能
2020/08/19 jQuery
Python的collections模块中的OrderedDict有序字典
2016/07/07 Python
Pyinstaller将py打包成exe的实例
2018/03/31 Python
实例讲解Python中浮点型的基本内容
2019/02/11 Python
python3实现用turtle模块画一棵随机樱花树
2019/11/21 Python
Python2与Python3的区别详解
2020/02/09 Python
MATLAB数学建模之画图汇总
2020/07/16 Python
CSS3 选择器 属性选择器介绍
2012/01/21 HTML / CSS
CSS3制作缩略图的详细过程
2016/07/08 HTML / CSS
施华洛世奇天猫官方旗舰店:SWAROVSKI
2017/04/17 全球购物
白俄罗斯大卖场:21vek.by
2019/07/25 全球购物
C#中有没有静态构造函数,如果有是做什么用的?
2016/06/04 面试题
如果有两个类A,B,怎么样才能使A在发生一个事件的时候通知B
2016/03/12 面试题
文明之星事迹材料
2014/05/09 职场文书
学校火灾防控方案
2014/06/09 职场文书
淘宝活动总结范文
2014/06/26 职场文书
自动化专业大学生职业生涯规划范文:爱拚才会赢
2014/09/12 职场文书
《火纹风花雪月无双》预告“神秘雇佣兵” 紫发剑客
2022/04/13 其他游戏
Linux安装Docker详细教程
2022/07/07 Servers