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 相关文章推荐
phpBB BBcode处理的漏洞
Oct 09 PHP
php 多个submit提交表单 处理方法
Jul 07 PHP
PHP根据IP判断地区名信息的示例代码
Mar 03 PHP
php文件服务实现虚拟挂载其他目录示例
Apr 17 PHP
ThinkPHP模板IF标签用法详解
Jul 01 PHP
Laravel 5框架学习之用户认证
Apr 09 PHP
Yii2分页的使用及其扩展方法详解
May 23 PHP
PHP实现的XML操作类【XML Library】
Dec 29 PHP
php实现与python进行socket通信的方法示例
Aug 30 PHP
PHP读取、解析eml文件及生成网页的方法示例
Sep 04 PHP
Ubuntu中支持PHP5与PHP7双版本的简单实现
Aug 19 PHP
php实现断点续传大文件示例代码
Jun 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 8小时时间差的解决方法小结
2009/12/22 PHP
PHP字符串函数系列之nl2br(),在字符串中的每个新行 (\n) 之前插入 HTML 换行符br
2011/11/10 PHP
如何用php获取程序执行的时间
2013/06/09 PHP
PHP中的gzcompress、gzdeflate、gzencode函数详解
2014/07/29 PHP
php字符串过滤与替换小结
2015/01/26 PHP
利用ajax和PHP实现简单的流程管理
2017/03/23 PHP
Thinkphp 框架基础之源码获取、环境要求与目录结构分析
2020/04/27 PHP
PHP加MySQL消息队列深入理解
2021/02/27 PHP
TFDN图片播放器 不错自动播放
2006/10/03 Javascript
javascript权威指南 学习笔记之javascript数据类型
2011/09/24 Javascript
js自执行函数的几种不同写法的比较
2012/08/16 Javascript
JavaScrip实现PHP print_r的数功能(三种方法)
2013/11/12 Javascript
javascript 通用loading动画效果实例代码
2014/01/14 Javascript
JS中使用Array函数shift和pop创建可忽略参数的例子
2014/05/28 Javascript
JavaScript实现N皇后问题算法谜题解答
2014/12/29 Javascript
基于jQuery的JavaScript模版引擎JsRender使用指南
2014/12/29 Javascript
JavaScript中使用Callback控制流程介绍
2015/03/16 Javascript
Javascript自执行匿名函数(function() { })()的原理浅析
2016/05/15 Javascript
JavaScript闭包的简单应用
2017/09/01 Javascript
vue 实现通过手机发送短信验证码注册功能
2018/04/19 Javascript
Vue.js 通过jQuery ajax获取数据实现更新后重新渲染页面的方法
2018/08/09 jQuery
node crawler如何添加promise支持
2020/02/01 Javascript
仿照Element-ui实现一个简易的$message方法
2020/09/14 Javascript
pyenv命令管理多个Python版本
2017/03/26 Python
基于Python实现的微信好友数据分析
2018/02/26 Python
妙用itchat! python实现久坐提醒功能
2019/11/25 Python
Python数据可视化处理库PyEcharts柱状图,饼图,线性图,词云图常用实例详解
2020/02/10 Python
css3和jquery实现的可折叠导航菜单适合放在手机网页的导航菜单
2014/09/02 HTML / CSS
什么叫做SQL注入,如何防止
2016/10/04 面试题
商场客服专员岗位职责
2014/06/13 职场文书
行政司机岗位职责
2015/04/10 职场文书
建筑工地资料员岗位职责
2015/04/13 职场文书
创业计划书之儿童理发店
2019/09/27 职场文书
SpringBoot详解执行过程
2022/07/15 Java/Android
Flink 侧流输出源码示例解析
2022/09/23 Servers
CSS link与@import的区别和用法解析
2023/05/07 HTML / CSS