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 相关文章推荐
建立动态的WML站点(二)
Oct 09 PHP
网站当前的在线人数
Oct 09 PHP
php桌面中心(一) 创建数据库
Mar 11 PHP
linux系统上支持php的 iconv()函数的方法
Oct 01 PHP
PHP新手NOTICE错误常见解决方法
Dec 07 PHP
让PHP更快的提供文件下载的代码
Jun 13 PHP
PHP中常用的转义函数
Feb 28 PHP
Laravel 5框架学习之环境与配置
Apr 08 PHP
微信支付开发告警通知实例
Jul 12 PHP
Yii 2.0如何使用页面缓存方法示例
May 23 PHP
PHP 使用二进制保存用户状态的实例
Jan 29 PHP
php实现商城购物车的思路和源码分析
Jul 23 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
计数器详细设计
2006/10/09 PHP
实现PHP框架系列文章(6)mysql数据库方法
2016/03/04 PHP
Netbeans 8.2将支持PHP7 更精彩
2016/06/13 PHP
PHP 极验验证码实例讲解
2016/09/29 PHP
php版微信自定义回复功能示例
2016/12/05 PHP
js类中获取外部函数名的方法
2007/08/19 Javascript
基于jquery库的tab新形式使用
2012/11/16 Javascript
得到form下的所有的input的js代码
2013/11/07 Javascript
Jquery响应回车键直接提交表单操作代码
2014/07/25 Javascript
jquery实现鼠标点击后展开列表内容的导航栏效果
2015/09/14 Javascript
javascript数据结构之二叉搜索树实现方法
2015/11/25 Javascript
关于backbone url请求中参数带有中文存入数据库是乱码的快速解决办法
2016/06/13 Javascript
BootStrap 智能表单实战系列(二)BootStrap支持的类型简介
2016/06/13 Javascript
jQuery中slidedown与slideup方法用法示例
2016/09/16 Javascript
parabola.js抛物线与加入购物车效果的示例代码
2017/10/25 Javascript
详解Vue路由钩子及应用场景(小结)
2017/11/07 Javascript
javascript实现简单页面倒计时
2021/03/02 Javascript
[03:13]DOTA2-DPC中国联赛1月25日Recap集锦
2021/03/11 DOTA
python 实现分页显示从es中获取的数据方法
2018/12/26 Python
Python小游戏之300行代码实现俄罗斯方块
2019/01/04 Python
简单介绍python封装的基本知识
2019/08/10 Python
python zip()函数的使用示例
2020/09/23 Python
Jo Malone美国官网:祖玛珑香水
2017/03/27 全球购物
美国在线眼镜商城:Eyeglasses.com
2017/06/26 全球购物
Yves Rocher捷克官方网站:植物化妆品的创造者
2019/07/31 全球购物
上海中网科技笔试题
2012/02/19 面试题
简历自我评价怎么写好呢?
2014/01/04 职场文书
简历上的自我评价
2014/02/03 职场文书
企业管理毕业生求职信范文
2014/03/07 职场文书
大学英语专业求职信
2014/06/21 职场文书
租房安全协议书
2014/08/20 职场文书
警告通知
2015/04/25 职场文书
学生病假条怎么写
2015/08/17 职场文书
《詹天佑》教学反思
2016/02/20 职场文书
mysql多表查询-笔记七
2021/04/05 MySQL
HttpClient实现表单提交上传文件
2022/08/14 Java/Android