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的十大要点(上)
Feb 04 PHP
初次接触php抽象工厂模式(Elgg)
Mar 21 PHP
PHP 金额数字转换成英文
May 06 PHP
php中修改浏览器的User-Agent来伪装你的浏览器和操作系统
Jul 29 PHP
打造超酷的PHP数据饼图效果实现代码
Nov 23 PHP
php实现的支持imagemagick及gd库两种处理的缩略图生成类
Sep 23 PHP
thinkphp特殊标签用法概述
Nov 24 PHP
基础的WordPress插件制作教程
Nov 24 PHP
php rmdir使用递归函数删除非空目录实例详解
Oct 20 PHP
PHP 进程池与轮询调度算法实现多任务的示例代码
Nov 26 PHP
PHP设计模式之迭代器模式Iterator实例分析【对象行为型】
Apr 26 PHP
聊聊 PHP 8 新特性 Attributes
Aug 19 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中json_encode处理gbk与gb2312中文乱码问题的解决方法
2014/07/10 PHP
php阿拉伯数字转中文人民币大写
2015/12/21 PHP
Mootools 1.2教程(21)——类(二)
2009/09/15 Javascript
JavaScript使用过程中需要注意的地方和一些基本语法
2010/08/26 Javascript
(jQuery,mootools,dojo)使用适合自己的编程别名命名
2010/09/14 Javascript
js给页面加style无效果的解决方法
2014/01/20 Javascript
自定义jquery模态窗口插件无法在顶层窗口显示问题
2014/05/29 Javascript
jquery简单实现带渐显效果的选项卡菜单代码
2015/09/01 Javascript
JavaScript面试题大全(推荐)
2016/09/22 Javascript
javascript的document中的动态添加标签实现方法
2016/10/24 Javascript
JS IOS/iPhone的Safari浏览器不兼容Javascript中的Date()问题如何解决
2016/11/11 Javascript
JS重载实现方法分析
2016/12/16 Javascript
原生js实现旋转木马轮播图效果
2017/02/27 Javascript
nodejs+express搭建多人聊天室步骤
2018/02/12 NodeJs
JS函数内部属性之arguments和this实例解析
2018/10/07 Javascript
vue中v-for通过动态绑定class实现触发效果
2018/12/06 Javascript
vue生命周期与钩子函数简单示例
2019/03/13 Javascript
Angular封装搜索框组件操作示例
2019/04/25 Javascript
django js 实现表格动态标序号的实例代码
2019/07/12 Javascript
[04:28]2014DOTA2国际邀请赛 采访小兔子LGD挺进钥匙体育馆
2014/07/14 DOTA
python通过BF算法实现关键词匹配的方法
2015/03/13 Python
python判断给定的字符串是否是有效日期的方法
2015/05/13 Python
Python的消息队列包SnakeMQ使用初探
2016/06/29 Python
tensorflow实现简单的卷积神经网络
2018/05/24 Python
python 2.7.13 安装配置方法图文教程
2018/09/18 Python
Python3安装pip工具的详细步骤
2019/10/14 Python
python属于软件吗
2020/06/18 Python
出纳岗位职责范本
2013/12/01 职场文书
综合办公室个人的自我评价
2013/12/22 职场文书
期末考试动员演讲稿
2014/01/10 职场文书
普通员工辞职信
2014/01/17 职场文书
公司委托书格式
2014/08/01 职场文书
领导四风问题整改措施思想汇报
2014/10/13 职场文书
个人简历求职信范文
2015/03/20 职场文书
感谢信
2019/04/11 职场文书
用Java实现简单计算器功能
2021/07/21 Java/Android