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脚本的10个技巧(3)
Oct 09 PHP
php引用地址改变变量值的问题
Mar 23 PHP
php中用memcached实现页面防刷新功能
Aug 19 PHP
jquery获取多个checkbox的值异步提交给php的方法
Jun 24 PHP
PHP语法小结之基础和变量
Nov 22 PHP
PHP文件及文件夹操作之创建、删除、移动、复制
Jul 13 PHP
使用WAMP搭建PHP本地开发环境
May 10 PHP
php使用flock阻塞写入文件和非阻塞写入文件的实例讲解
Jul 10 PHP
php中html_entity_decode实现HTML实体转义
Jun 13 PHP
PHP获取MySQL执行sql语句的查询时间方法
Aug 21 PHP
PHP函数用法详解【初始化、嵌套、内置函数等】
Jun 02 PHP
PHP基于phpqrcode类生成二维码的方法示例详解
Aug 07 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 Session机制简介及用法
2014/08/19 PHP
PHP检查端口是否可以被绑定的方法示例
2018/08/09 PHP
鼠标图片振动代码
2006/07/06 Javascript
第一个JavaScript入门基础 document.write输出
2010/02/22 Javascript
终于解决了IE8不支持数组的indexOf方法
2013/04/03 Javascript
JQuery在页面中添加和除移DOM示例代码
2013/06/24 Javascript
JavaScript var声明变量背后的原理示例解析
2013/10/12 Javascript
Jquery each方法跳出循环,并获取返回值(实例讲解)
2013/12/12 Javascript
jquery中子元素和后代元素的区别示例介绍
2014/04/02 Javascript
js监听鼠标事件控制textarea输入字符串的个数
2014/09/29 Javascript
jquery+ajax请求且带返回值的代码
2015/08/12 Javascript
js实现选中页面文字将其分享到新浪微博
2015/11/05 Javascript
jQuery实现ajax调用WCF服务的方法(附带demo下载)
2015/12/04 Javascript
JS解决IOS中拍照图片预览旋转90度BUG的问题
2017/09/13 Javascript
vue 实现 ios 原生picker 效果及实现思路解析
2017/12/06 Javascript
vue组件表单数据回显验证及提交的实例代码
2018/08/30 Javascript
jQuery超简单遮罩层实现方法示例
2018/09/06 jQuery
javascript设计模式 ? 命令模式原理与用法实例分析
2020/04/20 Javascript
vue实现给div绑定keyup的enter事件
2020/07/31 Javascript
Python正则表达式常用函数总结
2017/06/24 Python
python实现requests发送/上传多个文件的示例
2018/06/04 Python
Python 实现「食行生鲜」签到领积分功能
2018/09/26 Python
python中使用while循环的实例
2019/08/05 Python
python读取excel进行遍历/xlrd模块操作
2020/07/12 Python
python中time.ctime()实例用法
2021/02/03 Python
HTML5中FileReader接口使用方法实例详解
2017/08/26 HTML / CSS
New Era英国官网:美国棒球帽品牌
2018/03/21 全球购物
自考生自我鉴定范文
2013/10/01 职场文书
大学生村官承诺书
2014/03/28 职场文书
乡镇党员群众路线教育实践活动对照检查材料思想汇报
2014/10/05 职场文书
2014财务年终工作总结
2014/12/08 职场文书
销售员岗位职责
2015/02/10 职场文书
2015年政风行风工作总结
2015/04/21 职场文书
亲情作文之母爱
2019/09/25 职场文书
Python绘画好看的星空图
2022/03/17 Python
详解Alibaba Java诊断工具Arthas查看Dubbo动态代理类
2022/04/08 Java/Android