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安装问题
Oct 09 PHP
建立动态的WML站点(二)
Oct 09 PHP
PHP页面间参数传递的四种方法详解
Jun 09 PHP
使用PHP遍历文件目录与清除目录中文件的实现详解
Jun 24 PHP
php对数组排序代码分享
Feb 24 PHP
php实现httpclient类示例
Apr 08 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(一)
Jun 23 PHP
php事务处理实例详解
Jul 11 PHP
PHP图片处理之图片背景、画布操作
Nov 19 PHP
Symfony2学习笔记之控制器用法详解
Mar 17 PHP
thinkphp集成前端脚手架Vue-cli的教程图解
Aug 30 PHP
php 下 html5 XHR2 + FormData + File API 上传文件操作实例分析
Feb 28 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
解析csv数据导入mysql的方法
2013/07/01 PHP
Laravel中扩展Memcached缓存驱动实现使用阿里云OCS缓存
2015/02/10 PHP
php获取ajax的headers方法与内容实例
2017/12/27 PHP
PDO::errorInfo讲解
2019/01/28 PHP
php中关于换行的实例写法
2019/09/26 PHP
javascript同步Import,同步调用外部js的方法
2008/07/08 Javascript
js 动态文字滚动的例子
2011/01/17 Javascript
使用JavaScript构建JSON格式字符串实现步骤
2013/03/22 Javascript
JavaScript计算字符串中每个字符出现次数的小例子
2013/07/02 Javascript
省市选择的简单实现(基于zepto.js)
2016/06/21 Javascript
ionic2 tabs使用 Modal底部tab弹出框
2016/12/30 Javascript
BootStrap数据表格实例代码
2017/09/13 Javascript
实例讲解javascript实现异步图片上传方法
2017/12/05 Javascript
前端MVVM框架解析之双向绑定
2018/01/24 Javascript
vuex 解决报错this.$store.commit is not a function的方法
2018/12/17 Javascript
微信小程序自定义弹窗实现详解(可通用)
2019/07/04 Javascript
Smartour 让网页导览变得更简单(推荐)
2019/07/19 Javascript
ES5 模拟 ES6 的 Symbol 实现私有成员功能示例
2020/05/06 Javascript
Python考拉兹猜想输出序列代码实践
2019/07/05 Python
浅谈tensorflow模型保存为pb的各种姿势
2020/05/25 Python
如何学习Python time模块
2020/06/03 Python
pytorch 限制GPU使用效率详解(计算效率)
2020/06/27 Python
HTML5 解析规则分析
2009/08/14 HTML / CSS
Myprotein荷兰官网:欧洲第一运动营养品牌
2020/07/11 全球购物
C语言编程题
2015/03/09 面试题
介绍一下EJB的体系结构
2012/08/01 面试题
银行会计业务的个人自我评价
2013/11/02 职场文书
情人节活动策划方案
2014/02/27 职场文书
公务员平时考核实施方案
2014/03/11 职场文书
蓝颜请假条
2014/04/11 职场文书
幼儿园大班评语大全
2014/04/17 职场文书
关于保护环境的建议书
2014/05/13 职场文书
汽车销售经理岗位职责
2014/06/09 职场文书
迎国庆演讲稿
2014/09/15 职场文书
新郎婚礼致辞
2015/07/27 职场文书
Python 如何安装Selenium
2021/05/06 Python