php 後期靜態繫結
https://www.php.net/manual/zh/language.oop5.late-static-bindings.php
自 PHP 5.3.0 起,PHP 增加了一個叫做後期靜態繫結的功能,用於在繼承範圍內引用靜態呼叫的類。
準確說,後期靜態繫結工作原理是儲存了在上一個“非轉發呼叫”(non-forwarding call)的類名。當進行靜態方法呼叫時,該類名即為明確指定的那個(通常在 :: 運算子左側部分);當進行非靜態方法呼叫時,即為該物件所屬的類。所謂的“轉發呼叫”(forwarding call)指的是通過以下幾種方式進行的靜態呼叫:self::,parent::,static:: 以及 forward_static_call()。可用 get_called_class() 函式來得到被呼叫的方法所在的類名,static:: 則指出了其範圍。
該功能從語言內部角度考慮被命名為“後期靜態繫結”。“後期繫結”的意思是說,static:: 不再被解析為定義當前方法所在的類,而是在實際執行時計算的。也可以稱之為“靜態繫結”,因為它可以用於(但不限於)靜態方法的呼叫。
self:: 的限制
使用 self:: 或者 __CLASS__ 對當前類的靜態引用,取決於定義當前方法所在的類:
Example #1 self:: 用法
<?php
class A {
public static function who() {
echo __CLASS__;
}
public static function test() {
self::who();
}
}
class B extends A {
public static function who() {
echo __CLASS__;
}
}
B::test();
?>
以上例程會輸出:
A
後期靜態繫結的用法
後期靜態繫結本想通過引入一個新的關鍵字表示執行時最初呼叫的類來繞過限制。簡單地說,這個關鍵字能夠讓你在上述例子中呼叫 test() 時引用的類是 B 而不是 A。最終決定不引入新的關鍵字,而是使用已經預留的 static 關鍵字。
Example #2 static:: 簡單用法
<?php
class A {
public static function who() {
echo __CLASS__;
}
public static function test() {
static::who(); // 後期靜態繫結從這裡開始
}
}
class B extends A {
public static function who() {
echo __CLASS__;
}
}
B::test();
?>
以上例程會輸出:
B
Note:
在非靜態環境下,所呼叫的類即為該物件例項所屬的類。由於 $this-> 會在同一作用範圍內嘗試呼叫私有方法,而 static:: 則可能給出不同結果。另一個區別是 static:: 只能用於靜態屬性。
Example #3 非靜態環境下使用 static::
<?php
class A {
private function foo() {
echo "success!\n";
}
public function test() {
$this->foo();
static::foo();
}
}
class B extends A {
/* foo() will be copied to B, hence its scope will still be A and
* the call be successful */
}
class C extends A {
private function foo() {
/* original method is replaced; the scope of the new one is C */
}
}
$b = new B();
$b->test();
$c = new C();
$c->test(); //fails
?>
以上例程會輸出:
success!
success!
success!
Fatal error: Call to private method C::foo() from context 'A' in /tmp/test.php on line 9
上面將 private 改成 public 就不會報錯
class C extends A {
private function foo() {
/* original method is replaced; the scope of the new one is C */
}
}
改成
class C extends A {
public function foo() {
/* original method is replaced; the scope of the new one is C */
}
}
Note:
後期靜態繫結的解析會一直到取得一個完全解析了的靜態呼叫為止。另一方面,如果靜態呼叫使用 parent:: 或者 self:: 將轉發呼叫資訊。
Example #4 轉發和非轉發呼叫
<?php
class A {
public static function foo() {
static::who();
}
public static function who() {
echo __CLASS__."\n";
}
}
class B extends A {
public static function test() {
A::foo();
parent::foo();
self::foo();
}
public static function who() {
echo __CLASS__."\n";
}
}
class C extends B {
public static function who() {
echo __CLASS__."\n";
}
}
C::test();
?>
以上例程會輸出:
A
C
C
相關文章
- 對 PHP 後期靜態繫結的理解PHP
- 後期靜態繫結在PHP中的使用PHP
- 深入理解PHP物件導向之後期靜態繫結PHP物件
- Laravel 中的一個後期靜態繫結Laravel
- 介面(抽象類)與後期靜態繫結學習抽象
- PHP 物件導向 (七)訪問物件的方式及後期靜態繫結PHP物件
- 理解靜態繫結與動態繫結
- C++ — 靜態繫結與動態繫結C++
- PHP延遲靜態繫結:static關鍵字PHP
- PHP學習筆記——延遲靜態繫結PHP筆記
- C++的動態繫結和靜態繫結C++
- java繼承-靜態繫結和動態繫結Java繼承
- java中的靜態繫結與動態繫結Java
- 動態繫結和靜態繫結的簡單理解
- 深入理解 C++ 的動態繫結和靜態繫結C++
- Jni函式的靜態繫結函式
- 繫結變數在靜態sql和動態sql中變數SQL
- 14 #### 方法分類與使用場景(繫結、靜態、類方法)
- PHP靜態化技術PHP
- php生成靜態檔案PHP
- php 生成靜態頁面PHP
- PHP生成靜態頁面PHP
- PHP 中 static 靜態屬性和靜態方法的呼叫PHP
- PHP類的靜態(static)方法和靜態(static)變數PHP變數
- 動態繫結一
- PHP重定向與偽靜態PHP
- vue生命週期、雙向繫結Vue
- PHP 物件導向 (五)靜態方法PHP物件
- 關於php生成靜態問題PHP
- PHP 實現頁面靜態化PHP
- PHP的靜態變數介紹PHP變數
- Java中靜態跟非靜態的區別總結Java
- 動態連結庫與靜態連結庫
- JAVA動態繫結淺析Java
- 三、動態繫結屬性
- 動態繫結的心得 (轉)
- 網易校園招聘考察知識點--預設引數是編譯期間繫結的,而不是動態繫結編譯
- 關於php中靜態方法,靜態屬性的一些淺見PHP