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 相关文章推荐
PHP4引用文件语句的对比
Oct 09 PHP
Discuz!下Memcache缓存实现方法
May 28 PHP
PHP数组传递是值传递而非引用传递概念纠正
Jan 31 PHP
微信公众平台天气预报功能开发
Jul 06 PHP
微信支付PHP SDK之微信公众号支付代码详解
Dec 09 PHP
基于PHP实现数据分页显示功能
May 26 PHP
laravel中的错误与日志用法详解
Jul 26 PHP
yii2.0数据库迁移教程【多个数据库同时同步数据】
Oct 08 PHP
PHP查询分页的实现代码
Jun 09 PHP
实例讲解PHP页面静态化
Feb 05 PHP
解决laravel-admin 自己新建页面里 js 需要刷新一次的问题
Oct 03 PHP
PHP autoload使用方法及步骤详解
Sep 05 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
哪吒敖丙传:新人物二哥敖乙出场 小敖丙奶气十足
2020/03/08 国漫
drupal 代码实现URL重写
2011/05/04 PHP
php高级编程-函数-郑阿奇
2011/07/04 PHP
PHPUnit测试私有属性和方法功能示例
2018/06/12 PHP
goto语法在PHP中的使用教程
2020/09/17 PHP
PHP扩展安装方法步骤解析
2020/11/24 PHP
用JS剩余字数计算的代码
2008/07/03 Javascript
在UpdatePanel内jquery easyui效果失效的解决方法
2010/04/11 Javascript
javascript数字时钟示例分享
2014/04/23 Javascript
JS实现登录页面记住密码和enter键登录方法推荐
2016/05/10 Javascript
轻松理解JavaScript闭包
2017/03/14 Javascript
JavaScript函数表达式详解及实例
2017/05/05 Javascript
Mui使用jquery并且使用点击跳转新窗口的实例
2017/08/19 jQuery
关于vuejs中v-if和v-show的区别及v-show不起作用问题
2018/03/26 Javascript
Angularjs 根据一个select的值去设置另一个select的值方法
2018/08/13 Javascript
JavaScript简单实现的仿微博留言功能示例
2019/01/17 Javascript
微信小程序点击item使之滚动到屏幕中间位置
2020/03/25 Javascript
python编程培训 python培训靠谱吗
2018/01/17 Python
tensorflow saver 保存和恢复指定 tensor的实例讲解
2018/07/26 Python
对Python信号处理模块signal详解
2019/01/09 Python
Django之模板层的实现代码
2019/09/09 Python
python 深度学习中的4种激活函数
2020/09/18 Python
css3实例教程 一款纯css3实现的发光屏幕旋转特效
2014/12/07 HTML / CSS
解决CSS3的opacity属性带来的层叠顺序问题
2016/05/09 HTML / CSS
美国电力供应商店/电气批发商:USESI
2018/10/12 全球购物
建筑班组长岗位职责
2014/01/02 职场文书
市场营销战略计划书
2014/05/06 职场文书
团代会宣传工作方案
2014/05/08 职场文书
环保倡议书500字
2014/05/15 职场文书
校运会口号
2014/06/18 职场文书
动物科学专业求职信
2014/07/27 职场文书
工程质量保证书
2015/05/09 职场文书
董事长助理工作总结2015
2015/07/23 职场文书
简历中的自我评价应该这样写!
2019/07/12 职场文书
多表查询、事务、DCL
2021/04/05 MySQL
使用JS前端技术实现静态图片局部流动效果
2022/08/05 Javascript