萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 網路程式設計 >> PHP 程式設計

PHP 靜態方法與屬性深度解析

靜態成員基礎

使用 static 關鍵字宣告的屬性或方法稱為靜態成員。靜態方法無需實例化物件,直接透過 類別名::方法名() 呼叫;靜態屬性同樣透過 類別名::$屬性名 存取。

class A {
    static function fun() {
        // do something
    }
}
A::fun(); // 直接呼叫

靜態與非靜態的關鍵差異

核心差異在於生命週期與 $this 的可用性:

  • 靜態方法屬於類別,不屬於某個實例,因此無法使用 $this
  • 靜態方法中存取類別自身成員需用 self:: 或 static::(晚期靜態綁定)
  • 非靜態方法屬於物件實例,可使用 $this 存取實例屬性

實戰範例:錯誤示範與正確用法

class MyClass {
    public $num = 5;
    
    function __construct() {
        $this->num = 10;
    }
    
    function fun_1() {           // 非靜態方法
        echo "I am a public method named fun_1.\n";
        echo "The num of object is {$this->num}.\n";
    }
    
    static function fun_2() {    // 靜態方法
        echo "I am a static method named fun_2.\n";
    }
    
    function fun_3($n) {
        echo "The arg is {$n}\n";
    }
}

$m = new MyClass;
$m->fun_1();   // 正常
$m->fun_2();   // 正常(物件也可呼叫靜態方法)
$m->fun_3('test');

MyClass::fun_1(); // 錯誤:Using $this when not in object context
MyClass::fun_2(); // 正常
MyClass::fun_3('test'); // 錯誤

靜態屬性的生命週期特性

class User {
    public static $username;  // 靜態屬性
    public $password;         // 非靜態屬性
    
    function __construct($pwd) {
        echo 'Username: ' . self::$username;
        self::$username = 'admin';
        $this->password = $pwd;
    }
    
    public function show() {
        echo 'Username: ' . self::$username;
        echo 'Password: ' . $this->password;
    }
    
    public static function sshow() {
        echo 'Username: ' . self::$username;
        // echo 'Password: ' . $this->password; // 錯誤:靜態方法不可用 $this
    }
}

User::$username = 'root';      // 實例化前即可存取
$objUser = new User('123456');
$objUser->sshow();
unset($objUser);               // 物件銷毀
echo 'Username: ' . User::$username; // 靜態屬性依然存在

關鍵觀察:靜態屬性在類別實例化前就生效,物件銷毀後依然保留。這正是為什麼靜態方法無法存取非靜態成員——非靜態成員依賴具體實例存在。

存取權限總結

成員類型物件呼叫類別名呼叫可用 $this
非靜態方法✓✗ (PHP 7+ 嚴格模式報錯)✓
靜態方法✓✓✗
非靜態屬性✓✗✓
靜態屬性✗✓✗
copyright © 萬盛學電腦網 all rights reserved