首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 靜態類與靜態變量深度解析:self:: vs parent:: vs 類名::、靜態變量生命週期與遞歸應用

     編輯:PHP 相關知識

PHP 靜態類與靜態變量深度解析:self:: vs parent:: vs 類名::、靜態變量生命週期與遞歸應用

PHP static 關鍵字用於定義靜態屬性、靜態方法與函數內靜態變量。本文系統性解析靜態成員的訪問規則(self::/parent::/類名::/對象->)、非靜態方法靜態調用條件、靜態變量在函數與遞歸中的生命週期特性,並提供完整代碼驗證範例。

靜態類成員訪問規則總覽

訪問方式靜態屬性/方法非靜態屬性/方法前提條件
類名::member✅ 支援✅ 支援非靜態方法:不可使用 $this、不可調用非靜態成員
self::member✅ 支援❌ 不支援僅類內部使用,指向當前類(非晚期靜態綁定)
parent::member✅ 支援✅ 支援子類訪問父類,同非靜態限制
$obj->member✅ 支援(方法)✅ 支援需實例化對象,靜態屬性不建議此方式
static::member✅ 支援✅ 支援PHP 5.3+ 晚期靜態綁定 (LSB),指向實際調用類

完整驗證代碼:靜態屬性與方法繼承

<?php
class Person {
    // 靜態屬性
    public static $country = "中國";

    // 靜態方法
    public static function myCountry() {
        echo "我是 " . self::$country . " 人<br/>"; // 類內部用 self::
    }
}

class Student extends Person {
    function study() {
        echo "我是 " . parent::$country . " 人<br/>"; // 子類訪問父類用 parent::
    }
}

// 外部訪問:類名::
echo Person::$country . "<br/>";        // 輸出:中國
Person::myCountry();                       // 輸出:我是中國人

// 物件訪問靜態方法(可行但不推薦)
$p1 = new Person();
$p1->myCountry();                          // 輸出:我是中國人

// 子類繼承靜態成員
echo Student::$country . "<br/>";        // 輸出:中國
$t1 = new Student();
$t1->study();                              // 輸出:我是中國人
?>

輸出結果


中國
我是中國人
我是中國人
中國
我是中國人

關鍵語法規則速記

  • 類內部:self::$property、self::method()
  • 子類訪問父類:parent::$property、parent::method()
  • 外部訪問:ClassName::$property、ClassName::method()
  • 靜態方法也可用物件調用:$obj->staticMethod()(但無 $this 上下文)
  • 晚期靜態綁定:static::$property 解決繼承中 self:: 綁定過早問題

函數內靜態變量:生命週期與初始化限制

<?php
function foo() {
    static $int = 0;        // ✅ 正確:字面值初始化
    // static $int = 1 + 2;  // ❌ 錯誤:表達式不允許
    // static $int = sqrt(121); // ❌ 錯誤:函數呼叫不允許
    $int++;
    echo $int . "<br/>";
}

foo(); // 1
foo(); // 2
foo(); // 3
// 靜態變量僅初始化一次,後續調用保持上次值
?>

靜態變量實作計數器

<?php
function Test() {
    static $w3sky = 0;
    echo $w3sky . "<br/>";
    $w3sky++;
}

Test(); // 0
Test(); // 1
Test(); // 2
// 每次調用輸出遞增值
?>

靜態變量實作遞歸終止條件

<?php
function Test() {
    static $count = 0;
    $count++;
    echo $count . "<br/>";
    if ($count < 10) {
        Test(); // 遞歸調用
    }
    $count--; // 回溯時遞減(演示用,實際遞歸通常不需此步)
}

Test();
// 輸出 1 到 10,靜態變量跨遞歸層級共享
?>

靜態變量 vs 全域變量 vs 類靜態屬性

特性函數靜態變量全域變量類靜態屬性
作用域僅所在函數內可見全域可見(需 global)類作用域內,外部可用 類名:: 訪問
生命週期腳本執行期間持久腳本執行期間持久腳本執行期間持久
初始化首次執行到達時一次定義時類定義時
封裝性高(隱藏在函數內)低(污染全域命名空間)中(屬於類)
遞歸安全天然共享,適合計數需小心衝突需實例化或靜態調用

最佳實踐建議

  1. 靜態屬性用於共享資料:配置常數、快取實例、單例模式、資料庫連線池
  2. 靜態方法用於無狀態操作:工具函數、工廠方法、輔助類
  3. 避免濫用靜態:難以測試(無法 Mock)、隱性耦合、併發安全風險
  4. 函數靜態變量用於:函數級計數、遞歸狀態、單次初始化資源(如編譯正則、載入配置)
  5. 晚期靜態綁定:繼承體系中覆寫靜態屬性/方法時,內部調用請用 static:: 而非 self::

精通 static 機制,能寫出更高效、封裝性更強的 PHP 代碼,並避開繼承與遞歸中的常見陷阱。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved