延遲靜態綑綁的說明及範例

「延遲靜態綑綁」(late static binding)一直是 PHP 社群的熱門討論話題,隨著 PHP 5.3 得來臨,這項功能終於得以實現。究竟何謂「延遲靜態綑綁」?它有什麼用處?Sean Coates 在她的網誌提供了一個範例說明這種技術,並介紹它的實際用途。

簡單來說,「延遲靜態綑綁」就是把本來在編譯階段固定下來的表達式或變量,改成在執行階段才決定,當一個子類繼承了父類的「靜態綑綁」表達式,它的值便不能改變,很多情況下這未必是開發人員所希望見到的。這個構思已經討論了超過兩年,到了 PHP 5.3 我們終於可以見到它。

我們首先看看以下的範例:

 PHP |  copy code |? 
01
class Beer {
02
    const NAME = 'Beer!';
03
    public function getName() {
04
        return self::NAME;
05
    }
06
}
07
class Ale extends Beer {
08
    const NAME = 'Ale!';
09
}
10
$beerDrink = new Beer;
11
$aleDrink = new Ale;
12
echo "Beer is: " . $beerDrink->getName() ."\n";
13
echo "Ale is: " . $aleDrink->getName() ."\n";

執行的結果是:

Beer is: Beer!
Ale is: Beer! 

這裡 Ale 繼承了 Beer 的函式 getName(),由於 self::NAME 在編譯階段已經運算成 Beer! 並固定下來,Ale 也一拼繼承了 getName() 的傳回值 Beer!,這似乎不是開發人員所願見到的。這種情況在 PHP 5.3 不會改變,幸好 Zend 加入了一種新語法解決這個問題,就是使用 static 這個關鍵字,以下的原碼把本來的 self::NAME 改成 static::NAME:

 PHP |  copy code |? 
01
class Beer {
02
    const NAME = 'Beer!';
03
    public function getName() {
04
        return static::NAME;
05
    }
06
}
07
class Ale extends Beer {
08
    const NAME = 'Ale!';
09
}
10
$beerDrink = new Beer;
11
$aleDrink = new Ale;
12
echo "Beer is: " . $beerDrink->getName() ."\n";
13
echo "Ale is: " . $aleDrink->getName() ."\n";

結果將會是:

Beer is: Beer!
Ale is: Ale! 

新引入的 static:: 告訴編譯器無須在編譯階段把 static::NAME 運算出來,而是把整個表達式編譯成操作碼(opcode),讓 Zend Engine 在執行階段才運算它的值。

發表回覆

  

  

  

您可使用下列 these HTML標籤

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>