從這個名字的定義提取出兩個關鍵點,第一點靜態,也就是說這個功能只適用於靜態屬性或靜態方法。
第二點延遲綁定,這個根據下面代碼就可以很好的理解
看一下這個例子:
class A{ static $name = "Tom"; public function printName(){ echo self::$name."\n"; self::fun(); } static function fun(){ echo "A Class\n"; } } class B extends A{ static $name = "Jon"; static function fun(){ echo "B Class\n"; } } $obj = new B(); $obj->printName(); // 輸出結果 // Tom // A Class
我在printName函數里面使用了self關鍵字,self是指向當前類的"指針",
所以很多人會理想的認為輸出結果會是這樣:
// Join // B Class
是這樣的,在定義A類的是時候,在函數printName里面使用self關鍵字調用了靜態方法或屬性,
但是這個函數一旦定義好,A類的靜態方法和屬性就被綁定到函數了,不要去追究為什么,php就是這么實現的,
但是我們現在要實現這樣的效果,就是函數定義好后里面使用到的靜態方法和屬性不要立即綁定死,
而是根據最終繼承的類來確定綁定。
所以php在5.5以后使用了static關鍵字來解決這個問題,解決后的代碼例子如下:
class A{ static $name = "Tom"; public function printName(){ echo static::$name."\n"; static::fun(); } static function fun(){ echo "A Class\n"; } } class B extends A{ static $name = "Jon"; static function fun(){ echo "B Class\n"; } } $obj = new B(); $obj->printName(); // 輸出結果 // Join // B Class
大家可以在項目中自行挖掘使用場景,比如一個會員父類 class Vip
下面兩個子類分別是 超級會員 svip 和 年費會員 yvip
可以在兩個子類中分別重寫 static usergroup() 方法 或者其他靜態屬性 ,父類中使用延遲靜態綁定
這樣可以寫出很優雅的代碼