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 相关文章推荐
第五节 克隆 [5]
Oct 09 PHP
php $_SERVER[&quot;REQUEST_URI&quot;]获取值的通用解决方法
Jun 21 PHP
PHP垃圾回收机制简单说明
Jul 22 PHP
php调用MySQL存储过程的方法集合(推荐)
Jul 03 PHP
50个PHP程序性能优化的方法
Jun 02 PHP
使用PHPMailer实现邮件发送代码分享
Oct 23 PHP
php文件系统处理方法小结
May 23 PHP
PHP实现JS中escape与unescape的方法
Jul 11 PHP
PHPTree――php快速生成无限级分类
Mar 30 PHP
php实现二叉树中和为某一值的路径方法
Oct 14 PHP
laravel框架学习笔记之组件化开发实现方法
Feb 01 PHP
Thinkphp 框架扩展之应用模式实现方法分析
Apr 27 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
Sony CFR 320 修复改造
2020/03/14 无线电
摘自织梦CMS中的图片处理类
2015/08/08 PHP
thinkPHP数据查询常用方法总结【select,find,getField,query】
2017/03/15 PHP
php提交表单时保留多个空格及换行的文本样式的方法
2017/06/20 PHP
PHP判断访客是否手机端(移动端浏览器)访问的方法总结【4种方法】
2019/03/27 PHP
jquery 图片 上一张 下一张 链接效果(续篇)
2010/04/20 Javascript
javascript学习笔记(十八) 获得页面中的元素代码
2012/06/20 Javascript
js星星评分效果
2014/07/24 Javascript
AngularJS 实现JavaScript 动画效果详解
2016/09/08 Javascript
AngularJs $parse、$eval和$observe、$watch详解
2016/09/21 Javascript
jQuery基本选择器和层次选择器学习使用
2017/02/27 Javascript
详解react如何在组件中获取路由参数
2017/06/15 Javascript
JS实现的简单标签点击切换功能示例
2017/09/21 Javascript
解决Linux无法正常安装与卸载Node.js的方法
2018/01/19 Javascript
JS运动特效之同时运动实现方法分析
2018/01/24 Javascript
Vue中使用create-keyframe-animation与动画钩子完成复杂动画
2019/04/09 Javascript
JavaScript类的继承多种实现方法
2020/05/30 Javascript
微信小程序仿抖音短视频切换效果的实例代码
2020/06/24 Javascript
Python简单网络编程示例【客户端与服务端】
2017/05/26 Python
Python编程argparse入门浅析
2018/02/07 Python
Python学生信息管理系统修改版
2018/03/13 Python
python 请求服务器的实现代码(http请求和https请求)
2018/05/25 Python
Python中property函数用法实例分析
2018/06/04 Python
python实现将一个数组逆序输出的方法
2018/06/25 Python
python使用tcp实现局域网内文件传输
2020/03/20 Python
基于python的列表list和集合set操作
2019/11/24 Python
Python2与Python3关于字符串编码处理的差别总结
2020/09/07 Python
python try...finally...的实现方法
2020/11/25 Python
伦敦著名的运动鞋综合商店:Footpatrol
2019/03/25 全球购物
Bed Bath & Beyond加拿大官网:购买床上用品、浴巾、厨房电器等
2019/10/04 全球购物
马来西亚奢侈品牌购物商城:Valiram 247
2020/09/29 全球购物
社会学专业求职信
2014/07/17 职场文书
2014年重阳节活动策划方案书
2014/09/16 职场文书
党的群众路线教育实践活动个人对照检查材料(医生)
2014/11/05 职场文书
uwsgi+nginx代理Django无法访问静态资源的解决
2021/05/10 Servers
CentOS 7安装mysql5.7使用XtraBackUp备份工具命令详解
2022/04/12 MySQL