萬盛學電腦網

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

PHP 物件深度解析:傳遞機制、克隆、遍歷、類型約束、序列化、重載、靜態綁定、繼承可見性

1. 物件傳遞:引用計數器而非傳址

PHP 物件變數持有的是「物件識別符」(handle),指派/參數傳遞複製的是識別符,指向同一實體。不是傳址呼叫。

$a = new A; $a->foo = 1;
$b = $a;        // 複製識別符,$a、$b 指向同一物件
$b->foo = 2;    // $a->foo 也變 2
$c = new A;
$d = &$c;       // 真正的引用,$c、$d 綁定同一變數

2. 物件克隆:淺拷貝與 __clone()

class Sub { public $id; public function __construct() { $this->id = ++self::$cnt; } }
class Main {
    public $sub;
    public function __clone() {
        $this->sub = clone $this->sub; // 深拷貝子物件
    }
}
$o1 = new Main; $o1->sub = new Sub;
$o2 = clone $o1; // $o2->sub 為新物件,id 不同

3. 物件遍歷

  • foreach ($obj as $k => $v) 僅遍歷可見屬性(public、同類別內的 protected/private)。
  • 實作 Iterator 或 IteratorAggregate 可自定義遍歷行為。

4. 類型約束

function process(User $user, array $data, callable $cb) { ... }
class Foo implements LoggerInterface { ... } // 介面約束
// PHP 7.0+ 支援 scalar type: int, string, bool, float
// PHP 8.0+ 支援 union types: int|string
// 不支援標量類型約束於舊版,Trait 也不可作為類型約束

5. 序列化與還原

$str = serialize($obj);   // 字串含類別名、屬性值
$obj = unserialize($str); // 需先載入類別定義(autoload)
// 可實作 __sleep() 選擇序列化屬性、__wakeup() 還原後初始化

6. 重載(Overloading)魔術方法

限制:必須 public、不可 static、參數不可傳址、isset() 外無法用於重載屬性。

7. 靜態屬性/方法與晚期靜態綁定

class A {
    public static $who = 'A';
    public static function test() { echo self::$who . ' vs ' . static::$who . "\n"; }
}
class B extends A { public static $who = 'B'; }
A::test(); // A vs A
B::test(); // A vs B  ← static:: 解析為實際調用類別 B

8. 繼承與可見性

  • public:任意存取。
  • protected:類別內部 + 子類別。
  • private:僅定義該類別內部(子類別不可見、不可存取,但實體記憶體仍存在)。
  • 子類別可覆寫 protected/public 方法,不可縮小可見性。
copyright © 萬盛學電腦網 all rights reserved
方法觸發時機
__set($name, $value)寫入不可見屬性
__get($name)讀取不可見屬性
__isset($name)isset()/empty() 不可見屬性
__unset($name)unset() 不可見屬性
__call($name, $args)呼叫不可見實例方法
__callStatic($name, $args)靜態呼叫不可見方法