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 相关文章推荐
PHPwind整合最土系统用户同步登录实现方法
Dec 08 PHP
Apache2中实现多网站域名绑定的实现方法
Jun 01 PHP
提高define性能的php扩展hidef的安装和使用
Jun 14 PHP
生成随机字符串和验证码的类的PHP实例
Dec 24 PHP
php使用APC实现实时上传进度条功能
Oct 26 PHP
PHP扩展迁移为PHP7扩展兼容性问题记录
Feb 15 PHP
Zend Framework动作助手FlashMessenger用法详解
Mar 05 PHP
如何直接访问php实例对象中的private属性详解
Oct 12 PHP
PHP7 echo和print语句实例用法
Feb 15 PHP
详解如何实现Laravel的服务容器的方法示例
Apr 15 PHP
PHP使用 Imagick 扩展实现图片合成,圆角处理功能示例
Sep 09 PHP
ThinkPHP5.1+Ajax实现的无刷新分页功能示例
Feb 10 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数组中的重复值的实现代码
2011/07/17 PHP
PHP取进制余数函数代码
2012/01/19 PHP
ThinkPHP5.0多个文件上传后找不到临时文件的修改方法
2018/07/30 PHP
PHP使用PDO、mysqli扩展实现与数据库交互操作详解
2019/07/20 PHP
老鱼 浅谈javascript面向对象编程
2010/03/04 Javascript
Jquery index()方法 获取相应元素索引值
2012/10/12 Javascript
js根据给定的日期计算当月有多少天实现思路及代码
2013/02/25 Javascript
javascript:文字不间断向左移动的实例代码
2013/08/08 Javascript
兼容所有浏览器的js复制插件Zero使用介绍
2014/03/19 Javascript
JS通过分析userAgent属性来判断浏览器的类型及版本
2014/03/28 Javascript
node.js中的http.request方法使用说明
2014/12/14 Javascript
jQuery表单事件实例代码分享
2016/08/18 Javascript
javascript兼容性(实例讲解)
2017/08/15 Javascript
vue.js  父向子组件传参的实例代码
2017/10/29 Javascript
详解vue2.0 不同屏幕适配及px与rem转换问题
2018/02/23 Javascript
JavaScript中利用Array filter() 方法压缩稀疏数组
2018/02/24 Javascript
通过jquery toggleClass()属性制作文章段落更改背景颜色
2018/05/21 jQuery
VUE2.0 ElementUI2.0表格el-table自适应高度的实现方法
2018/11/28 Javascript
微信小程序:数据存储、传值、取值详解
2019/05/07 Javascript
vue实现公告栏文字上下滚动效果的示例代码
2020/06/16 Javascript
深入理解javascript中的this
2021/02/08 Javascript
Python中zfill()方法的使用教程
2015/05/20 Python
Python抓取电影天堂电影信息的代码
2016/04/07 Python
基于使用paramiko执行远程linux主机命令(详解)
2017/10/16 Python
python读取文本中的坐标方法
2018/10/14 Python
Window环境下Scrapy开发环境搭建
2018/11/18 Python
在pycharm下设置自己的个性模版方法
2019/07/15 Python
Python Django模板之模板过滤器与自定义模板过滤器示例
2019/10/18 Python
Django之富文本(获取内容,设置内容方式)
2020/05/21 Python
AMAVII眼镜官网:时尚和设计师太阳镜
2019/05/05 全球购物
天游软件面试
2013/11/23 面试题
创业女性典型材料
2014/05/02 职场文书
2014班子成员自我剖析材料思想汇报
2014/10/01 职场文书
奖学金个人总结
2015/03/04 职场文书
企业内部管理控制:银行存款控制制度范本
2020/01/10 职场文书
JavaScript异步操作中串行和并行
2021/11/20 Javascript