php static 和 self 都可以調用類中靜態的屬性和方法,但是他們還是具備一些本質上的不同,稍微不注意就會釀成程序邏輯錯誤,做個記錄。
兩者相同的時候
class A{
public static $ask="hello";
public function GetAsk(){
echo get_called_class()."<br/>";
echo self::$ask;
}
}
$b= new A();
$b->GetAsk();
class A{
public static $ask="hello";
public function GetAsk(){
echo get_called_class()."<br/>";
echo static::$ask;
}
}
$b= new A();
$b->GetAsk();
兩者輸出的內容都是相同:A以及hello。
可見 當兩者在非繼承情況下,表現得一致。
兩者展現差異的時候
class A{
public static $ask="hello";
public function GetAsk(){
echo get_called_class()."<br/>";
echo self::$ask;//hello
echo static::$ask;
}
}
class B extends A{
public static $ask="nihao";
public function GetNIhao(){
echo self::$ask;
echo static::$ask;
}
}
$b= new B();
$b->GetNIhao(); // 都輸出 nihao
class A{
public static $ask="hello";
public function GetAsk(){
echo get_called_class()."<br/>";
echo self::$ask; //hello
echo static::$ask; //nihao
}
}
class B extends A{
public static $ask="nihao";
public function GetNIhao(){
echo self::$ask;
echo static::$ask;
}
}
$b= new B();
$b->GetAsk(); //
這個時候,static輸出“nihao”,self輸出“hello”。
我們可以看到 static 表示維持,self代表定義。
總結
static始終會維持調用者內存地址,上面代碼中static始終指向$b所代表的的實例對象,在運行的時候就會優先去 本身類的定義域中去尋找存不存在該變量。
self就很粗暴,不管你是哪個類,它只看被調用的方法或者屬性變量定義在哪里,比如定義在父類($ask),那self就代表父類的地址引用。
所以static表示維持(維持調用者指針),self代表本身(定義者)。
還有一點:
new static / new self 他們之間的區別
一樣的原則:static維持,self定義。
new操作符會產生一個新的實例對象,那么問題就是,到底是哪個類的實例?
當我們沒得選的時候,他們表現的一致(沒有繼承的情況下)。
當存在繼承,static看誰在調用,self看唄調用的變量或者方法定義在哪里。
這一切討論的前提是:面向對象。