当前位置:首页 > PHP教程 > php高级应用 > 列表

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

发布:smiling 来源: PHP粉丝网  添加日期:2021-10-23 14:22:41 浏览: 评论:0 

这篇文章主要介绍了php闭包中使用use声明变量的作用域,结合实例形式分析了闭包中use声明变量作用域的相关原理与分析,需要的朋友可以参考下。

本文实例讲述了php闭包中使用use声明变量的作用域,分享给大家供大家参考,具体如下:

  1. <?php 
  2. function getClosure($i
  3.     $i = $i.'-'.date('H:i:s'); 
  4.     return function ($paramuse ($i) { 
  5.         echo "--- param: $param ---\n"
  6.         echo "--- i: $i ---\n"
  7.     }; 
  8. $c = getClosure(123); 
  9. $i = 456; 
  10. $c('test'); 
  11. sleep(3); 
  12. $c2 = getClosure(123); 
  13. $c2('test'); 
  14. $c('test'); 
  15. /* 
  16. output: 
  17. --- param: test --- 
  18. --- i: 123-21:36:52 --- 
  19. --- param: test --- 
  20. --- i: 123-21:36:55 --- 
  21. --- param: test --- 
  22. --- i: 123-21:36:52 --- 
  23. */ 

如上,闭包中使用use声明的变量来自于生成闭包实例时所在作用域内的同名变量,而不是来自于运行闭包时所在作用域内的同名变量。

而闭包的函数参数则是和正常的函数参数一样来自于运行时所在作用域内的同名变量。

以下为opcode:

  1. Finding entry points 
  2. Branch analysis from position: 0 
  3. Jump found. Position 1 = -2 
  4. filename:       /tmp/testclosure.php 
  5. function name:  (null) 
  6. number of ops:  20 
  7. compiled vars:  !0 = $c, !1 = $i, !2 = $c2 
  8. line     #* E I O op                           fetch          ext  return  operands 
  9. ------------------------------------------------------------------------------------- 
  10.    2     0  E >   NOP 
  11.   11     1        SEND_VAL                                                 123 
  12.          2        DO_FCALL                                      1  $0      'getclosure' 
  13.          3        ASSIGN                                                   !0, $0 
  14.   12     4        ASSIGN                                                   !1, 456 
  15.   13     5        INIT_FCALL_BY_NAME                                       !0 
  16.          6        SEND_VAL                                                 'test' 
  17.          7        DO_FCALL_BY_NAME                              1 
  18.   14     8        SEND_VAL                                                 3 
  19.          9        DO_FCALL                                      1          'sleep' 
  20.   15    10        SEND_VAL                                                 123 
  21.         11        DO_FCALL                                      1  $5      'getclosure' 
  22.         12        ASSIGN                                                   !2, $5 
  23.   16    13        INIT_FCALL_BY_NAME                                       !2 
  24.         14        SEND_VAL                                                 'test' 
  25.         15        DO_FCALL_BY_NAME                              1 
  26.   17    16        INIT_FCALL_BY_NAME                                       !0 
  27.         17        SEND_VAL                                                 'test' 
  28.         18        DO_FCALL_BY_NAME                              1 
  29.   29    19      > RETURN                                                   1 
  30. Function %00%7Bclosure%7D%2Ftmp%2Ftestclosure.php0x7fb0115f505: 
  31. Finding entry points 
  32. Branch analysis from position: 0 
  33. Jump found. Position 1 = -2 
  34. filename:       /tmp/testclosure.php 
  35. function name:  {closure} 
  36. number of ops:  12 
  37. compiled vars:  !0 = $param, !1 = $i 
  38. line     #* E I O op                           fetch          ext  return  operands 
  39. ------------------------------------------------------------------------------------- 
  40.    5     0  E >   RECV                                             !0 
  41.          1        FETCH_R                      static              $0      'i' 
  42.          2        ASSIGN                                                   !1, $0 
  43.    6     3        ADD_STRING                                       ~2      '---+param%3A+' 
  44.          4        ADD_VAR                                          ~2      ~2, !0 
  45.          5        ADD_STRING                                       ~2      ~2, '+---%0A' 
  46.          6        ECHO                                                     ~2 
  47.    7     7        ADD_STRING                                       ~3      '---+i%3A+' 
  48.          8        ADD_VAR                                          ~3      ~3, !1 
  49.          9        ADD_STRING                                       ~3      ~3, '+---%0A' 
  50.         10        ECHO                                                     ~3 
  51.    8    11      > RETURN                                                   null 
  52. End of function %00%7Bclosure%7D%2Ftmp%2Ftestclosure.php0x7fb0115f505 
  53. Function getclosure: 
  54. Finding entry points 
  55. Branch analysis from position: 0 
  56. Jump found. Position 1 = -2 
  57. filename:       /tmp/testclosure.php 
  58. function name:  getClosure 
  59. number of ops:  9 
  60. compiled vars:  !0 = $i 
  61. line     #* E I O op                           fetch          ext  return  operands 
  62. ------------------------------------------------------------------------------------- 
  63.    2     0  E >   RECV                                             !0 
  64.    4     1        CONCAT                                           ~0      !0, '-' 
  65.          2        SEND_VAL                                                 'H%3Ai%3As' 
  66.          3        DO_FCALL                                      1  $1      'date' 
  67.          4        CONCAT                                           ~2      ~0, $1 
  68.          5        ASSIGN                                                   !0, ~2 
  69.    5     6        DECLARE_LAMBDA_FUNCTION                                  '%00%7Bclosure%7D%2Ftmp%2Ftestclosure.php0x7fb0115f5051' 
  70.    8     7      > RETURN                                                   ~4 
  71.    9     8*     > RETURN                                                   null 
  72. End of function getclosure 

如上,闭包函数的op_array(相当于类定义)在编译期完成,但在运行期生成闭包实例(相当于类实例)时会为不同实例绑定不同的use静态变量(在DECLARE_LAMBDA_FUNCTION中完成)。

Tags: php闭包 use声明变量

分享到: