1. 程式人生 > >php 5.3新增的閉包語法介紹function() use() {}

php 5.3新增的閉包語法介紹function() use() {}

vars .net details article body 初始 bar amp bin

[php] view plain copy
  1. <?php
  2. /**
  3. * author: selfimpr
  4. * mail: [email protected]
  5. * blog: http://blog.csdn.net/lgg201
  6. * 下面提到的代碼在PHP5.3以上版本運行通過.
  7. */
  8. function callback($callback) {
  9. $callback();
  10. }
  11. //輸出: This is a anonymous function.<br />/n
  12. //這裏是直接定義一個匿名函數進行傳遞, 在以往的版本中, 這是不可用的.
  13. //現在, 這種語法非常舒服, 和javascript語法基本一致, 之所以說基本呢, 需要繼續向下看
  14. //結論: 一個舒服的語法必然會受歡迎的.
  15. callback(function() {
  16. print "This is a anonymous function.<br />/n";
  17. });
  18. //輸出: This is a closure use string value, msg is: Hello, everyone.<br />/n
  19. //這裏首先定義了一個閉包, 這次戶口本上有名字了...
  20. //use, 一個新鮮的家夥...
  21. //眾所周知, 閉包: 內部函數使用了外部函數中定義的變量.
  22. //在PHP新開放的閉包語法中, 我們就是用use來使用閉包外部定義的變量的.
  23. //這裏我們使用了外部變量$msg, 定義完之後, 又對其值進行了改變, 閉包被執行後輸出的是原始值
  24. //結論: 以傳值方式傳遞的基礎類型參數, 閉包use的值在閉包創建是就確定了.
  25. $msg = "Hello, everyone";
  26. $callback = function () use ($msg) {
  27. print "This is a closure use string value, msg is: $msg. <br />/n";
  28. };
  29. $msg = "Hello, everybody";
  30. callback($callback);
  31. //輸出: This is a closure use string value lazy bind, msg is: Hello, everybody.<br />/n
  32. //換一種引用方式, 我們使用引用的方式來use
  33. //可以發現這次輸出是閉包定義後的值...
  34. //這個其實不難理解, 我們以引用方式use, 那閉包use的是$msg這個變量的地址
  35. //當後面對$msg這個地址上的值進行了改變之後, 閉包內再輸出這個地址的值時, 自然改變了.
  36. $msg = "Hello, everyone";
  37. $callback = function () use (&$msg) {
  38. print "This is a closure use string value lazy bind, msg is: $msg. <br />/n";
  39. };
  40. $msg = "Hello, everybody";
  41. callback($callback);
  42. //輸出: This is a closure use object, msg is: Hello, everyone.<br />/n
  43. //閉包中輸出的是之前被拷貝的值為Hello, everyone的對象, 後面是對$obj這個名字的一個重新賦值.
  44. //可以這樣考慮
  45. //1. obj是對象Hello, everyone的名字
  46. //2. 對象Hello, everyone被閉包use, 閉包產生了一個對Hello, everyone對象的引用
  47. //3. obj被修改為Hello, everybody這個對象的名字
  48. //4. 註意, 是名字obj代表的實體變了, 而不是Hello, everyone對象, 那自然閉包的輸出還是前面的Hello, everyone
  49. $obj = (object) "Hello, everyone";
  50. $callback = function () use ($obj) {
  51. print "This is a closure use object, msg is: {$obj->scalar}. <br />/n";
  52. };
  53. $obj = (object) "Hello, everybody";
  54. callback($callback);
  55. //輸出: This is a closure use object, msg is: Hello, everybody.<br />/n
  56. //還是按照上面的步驟, 按部就班的來吧:
  57. //1. obj名字指向Hello, everyone對象
  58. //2. 閉包產生一個引用指向Hello, everyone對象
  59. //3. 修改obj名字指向的對象(即Hello, everyone對象)的scalar值
  60. //4. 執行閉包, 輸出的自然是Hello, everybody, 因為其實只有一個真正的對象
  61. $obj = (object) "Hello, everyone";
  62. $callback = function () use ($obj) {
  63. print "This is a closure use object, msg is: {$obj->scalar}. <br />/n";
  64. };
  65. $obj->scalar = "Hello, everybody";
  66. callback($callback);
  67. //輸出: This is a closure use object lazy bind, msg is: Hello, everybody.<br />/n
  68. //閉包引用的是什麽呢? &$obj, 閉包產生的引用指向$obj這個名字所指向的地址.
  69. //因此, 無論obj怎麽變化, 都是逃不脫的....
  70. //所以, 輸出的就是改變後的值
  71. $obj = (object) "Hello, everyone";
  72. $callback = function () use (&$obj) {
  73. print "This is a closure use object lazy bind, msg is: {$obj->scalar}. <br />/n";
  74. };
  75. $obj = (object) "Hello, everybody";
  76. callback($callback);
  77. /**
  78. * 一個利用閉包的計數器產生器
  79. * 這裏其實借鑒的是python中介紹閉包時的例子...
  80. * 我們可以這樣考慮:
  81. * 1. counter函數每次調用, 創建一個局部變量$counter, 初始化為1.
  82. * 2. 然後創建一個閉包, 閉包產生了對局部變量$counter的引用.
  83. * 3. 函數counter返回創建的閉包, 並銷毀局部變量, 但此時有閉包對$counter的引用,
  84. * 它並不會被回收, 因此, 我們可以這樣理解, 被函數counter返回的閉包, 攜帶了一個遊離態的
  85. * 變量.
  86. * 4. 由於每次調用counter都會創建獨立的$counter和閉包, 因此返回的閉包相互之間是獨立的.
  87. * 5. 執行被返回的閉包, 對其攜帶的遊離態變量自增並返回, 得到的就是一個計數器.
  88. * 結論: 此函數可以用來生成相互獨立的計數器.
  89. */
  90. function counter() {
  91. $counter = 1;
  92. return function() use(&$counter) {return $counter ++;};
  93. }
  94. $counter1 = counter();
  95. $counter2 = counter();
  96. echo "counter1: " . $counter1() . "<br />/n";
  97. echo "counter1: " . $counter1() . "<br />/n";
  98. echo "counter1: " . $counter1() . "<br />/n";
  99. echo "counter1: " . $counter1() . "<br />/n";
  100. echo "counter2: " . $counter2() . "<br />/n";
  101. echo "counter2: " . $counter2() . "<br />/n";
  102. echo "counter2: " . $counter2() . "<br />/n";
  103. echo "counter2: " . $counter2() . "<br />/n";
  104. ?>

php 5.3新增的閉包語法介紹function() use() {}