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物件
- PHP 物件導向 (七)訪問物件的方式及後期靜態繫結PHP物件
- 介面(抽象類)與後期靜態繫結學習抽象
- 理解靜態繫結與動態繫結
- C++的動態繫結和靜態繫結C++
- java中的靜態繫結與動態繫結Java
- 延遲靜態繫結——static
- 14 #### 方法分類與使用場景(繫結、靜態、類方法)
- PHP重定向與偽靜態PHP
- PHP 物件導向 (五)靜態方法PHP物件
- 關於php生成靜態問題PHP
- PHP 實現頁面靜態化PHP
- vue生命週期、雙向繫結Vue
- Java中靜態跟非靜態的區別總結Java
- 動態連結庫與靜態連結庫
- JAVA動態繫結淺析Java
- 三、動態繫結屬性
- PHP工具箱:PHPStan —— PHP 靜態程式碼分析工具PHP
- 靜態連結之深度解剖
- vue 動態繫結 v-modelVue
- 動態繫結 input v-model
- 關於動態字串的繫結字串
- Vue select 繫結動態變數Vue變數
- Vue 動態繫結CSS樣式VueCSS
- 【連結 1】與靜態連結庫連結
- PHP獲取動態跳轉後的真實連結PHP
- 介面的繫結方案和動態SQLSQL
- class 和 style 資料動態繫結
- 域名繫結動態IP實戰案例
- 靜態域與靜態方法
- C#資料結構-靜態連結串列C#資料結構
- 如何繫結多個後臺模組
- [原始碼解析] Pytorch 如何實現後向傳播 (2)---- 引擎靜態結構原始碼PyTorch
- SARIF:靜態分析結果交換格式
- 動態生成的html元素繫結click事件HTML事件