匿名函數和閉包

真正的匿名函數php

在PHP5.3引入的衆多功能中, 除了匿名函數還有一個特性值得講講: 新引入的__invoke 魔幻方法。閉包

這個魔幻方法被調用的時機是: 當一個對象當作函數調用的時候, 若是對象定義了__invoke魔幻方法則這個函數會被調用, 這和C++中的操做符重載有些相似, 例如能夠像下面這樣使用函數

###魔術方法__invoke.net

<?php
class Callme {
    public function __invoke($phone_num) {
        echo "Hello: $num";
    }
}
 
$call = new Callme();
$call(13810688888); // "Hello: 13810688888
?>

#匿名函數的實現 前面介紹了將對象做爲函數調用的方法, 聰明的你可能想到在PHP實現匿名函數的方法了,PHP中的匿名函數就的確是經過這種方式實現的。 咱們先來驗證一下:code

<?php
$func = function() {
    echo "Hello, anonymous function";
}
 
echo gettype($func);    // object
echo get_class($func);  // Closure
?>

原來匿名函數也只是一個普通的類而已.對象

#閉包的使用ip

PHP使用閉包(Closure)來實現匿名函數, 匿名函數最強大的功能也就在匿名函數所提供的一些動態特性以及閉包效果,作用域

匿名函數在定義的時候若是須要使用做用域外的變量須要使用以下的語法來實現:get

use語法io

<?php
$name = 'TIPI Tea';
$func = function() use($name) {
    echo "Hello, $name";
}
 
$func(); // Hello TIPI Team
?>

#use說明 這個use語句看起來挺彆扭的, 尤爲是和Javascript比起來, 不過這也應該是PHP-Core綜合考慮才使用的語法, 由於和Javascript的做用域不一樣, PHP在函數內定義的變量默認就是局部變量, 而在Javascript中則相反, 除了顯式定義的纔是局部變量, PHP在變異的時候則沒法肯定變量是局部變量仍是上層做用域內的變量, 固然也可能有辦法在編譯時肯定, 不過這樣對於語言的效率和複雜性就有很大的影響。

這個語法比較直接, 若是須要訪問上層做用域內的變量則須要使用use語句來申明, 這樣也簡單易讀, 說到這裏, 其實可使用use來實現相似global語句的效果。

匿名函數在每次執行的時候都能訪問到上層做用域內的變量, 這些變量在匿名函數被銷燬以前始終保存着本身的狀態, 例如以下的例子:

<?php
function getCounter() {
    $i = 0;
    return function() use($i) { // 這裏若是使用引用傳入變量: use(&$i)
        echo ++$i;
    };
}
 
$counter = getCounter();
$counter(); // 1
$counter(); // 1
?>

參考來源

相關文章
相關標籤/搜索