php教程

超轻量级php框架startmvc

php闭包中使用use声明变量的作用域实例分析

更新时间:2020-03-29 08:55:42 作者:startmvc
本文实例讲述了php闭包中使用use声明变量的作用域。分享给大家供大家参考,具体如下:<

本文实例讲述了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 闭包 use 变量 作用域