iT邦幫忙

3

PHP連載11

php

加入 iTHome 的第一篇 XD
跟大家分享一下 PHP 5.3 開始新增的 anonymouse function。
提到 anonymouse function 對於寫慣 Javascript 的人來說一定不陌生。
那什麼是 anonymouse function?
從字面上來說就是 "匿名函數" ,講白一點就是沒有名字的函數。

直接看 code 比較快。

<?php
$foo = function(){
    return 'foo';
};  //別忽略了結尾的 ; 
echo $foo();

輸出

foo

那匿名函數能做什麼用呢?
簡單的說就是 "你可以拿這個函數當變數傳遞"

像這樣

<?php
function getFooFunction()
{
    return function(){
        return 'foo';
    };
}
$foo = getFooFunction();
echo $foo();

或是

<?php
function doSomething($callback)
{
    //do something.
    $callback($result);
}

doSomething(function($result){
    //on finished
});

有沒有越來越像寫 JS 的感覺 XD

提到 anonymouse function 就不能不提到 closure。
closure 有人翻作 "閉包",但我相信初次見到的人一定有看沒有懂。
我們實際看 Code 比較快。

<?php
$foo = 'foo';

$getFoo = function($bar) use($foo)
{ 
    return $foo.$bar;
};
echo "\$foo = $foo\n";
echo "getFoo => ".$getFoo('bar')."\n";

$foo = 'new foo';

echo "\$foo = $foo\n";
echo "getFoo => ".$getFoo('bar')."\n";

輸出

$foo = foo
getFoo => foobar
$foo = new foo
getFoo => foobar

看完輸出結果後是不是更一頭霧水了。
我們來一行一行解釋吧。

function($bar) use($foo)
$bar這個參數是 呼叫 function 時傳遞給匿名函數的參數,就跟一般呼叫函數時傳遞的參數相同。
$foo這個參數是 建立 function 時傳遞給匿名函數的參數時。

我們看一下第4行產生匿名函數的地方,在產生的那個時間點 $foo 的值是 "foo",$foo 也會被 "凍結" 在那個狀態底下。

因此第14行 $getFoo() -> foobar
即使第11行 $foo = 'new foo';
可是 $getFoo 已經先被建立出來。
function 中的 $foo 還是停留在,建立時候的狀態,也就是 "foo"。

用個白話的方式解釋 use 這個 keyword 只是在建立函數時定義一個新的變數並且將他的值指定成外部同名稱的變數。function 中的 $foo 跟外部的 $foo 是兩個不相干的變數。

另外從 PHP 5.4 開始也支援了在匿名函數中使用 $this。
請注意 PHP5.3 不能這麼用。

<?php
class foo
{
    protected $bar = 'bar';
    
    function getBarFunction()
    {      
        return function()
        {
            return $this->bar;
        };
    }
}

$foo = new foo();
$barFunction = $foo->getBarFunction();
echo "barFunction => ".$barFunction()."\n";

輸出

barFunction => bar

這邊的 $this 有個比較特別的地方。
在 function 中的 $this 是視為這個 class 的成員之一,也就是說你可用來存取 protected 或是 private 成員。即使你是在外部呼叫這個 function。
特別注意的是,在 function 中使用 $this 並不需要特別宣告 use,直接使用就可以了。

如果對於 anonymouse function 有什麼遺漏或是錯誤的部份歡迎大家指正。


0
老鷹(eagle)
iT邦高手 1 級 ‧ 2014-03-10 14:47:03

筆記簽名謝謝
歡迎大大來連載~~!
抱抱

0
fillano
iT邦超人 1 級 ‧ 2014-03-10 16:40:32

來拜神了謝謝

0
rickyisme
iT邦新手 5 級 ‧ 2014-03-11 09:07:11

請大家多多指教飛

我要留言

立即登入留言