1. 程式人生 > >php 魔術方法 魔術常量

php 魔術方法 魔術常量

PHP中把以兩個下劃線__開頭的方法稱為魔術方法,這些方法在PHP中充當了舉足輕重的作用。 魔術方法包括:

  • __construct(),類的建構函式
  • __destruct(),類的解構函式
  • __call(),在物件中呼叫一個不可訪問方法時呼叫
  • __callStatic(),用靜態方式中呼叫一個不可訪問方法時呼叫
  • __get(),獲得一個類的成員變數時呼叫
  • __set(),設定一個類的成員變數時呼叫
  • __isset(),當對不可訪問屬性呼叫isset()empty()時呼叫
  • __unset(),當對不可訪問屬性呼叫unset()時被呼叫。
  • __sleep(),執行serialize()
    時,先會呼叫這個函式
  • __wakeup(),執行unserialize()時,先會呼叫這個函式
  • __toString(),類被當成字串時的迴應方法
  • __invoke(),呼叫函式的方式呼叫一個物件時的迴應方法
  • __set_state(),呼叫var_export()匯出類時,此靜態方法會被呼叫。
  • __clone(),當物件複製完成時呼叫

__construct()__destruct()

建構函式和解構函式應該不陌生,他們在物件建立和消亡時被呼叫。例如我們需要開啟一個檔案,在物件建立時開啟,物件消亡時關閉

<?php

class FileRead
{
    protected $handle = NULL;

    function __construct() {
        $this->handle = fopen();
    }

    function __destruct() {
        fclose($this->handle);
    }
}
?>

__call()__callStatic()

在物件中呼叫一個不可訪問方法時會呼叫這兩個方法,後者為靜態方法。這兩個方法我們在可變方法(Variable functions)呼叫中可能會用到。

<?php

class MethodTest
{
    public function __call($name, $arguments) {
        echo "Calling object method '$name' " . implode(', ', $arguments) . "\n";
    }

    public static function __callStatic($name, $arguments) {
        echo "Calling static method '$name' " . implode(', ', $arguments) . "\n";
    }
}

$obj = new MethodTest;
$obj->runTest('in object context');
MethodTest::runTest('in static context');
?>

__get()__set()__isset()__unset()

當get/set一個類的成員變數時呼叫這兩個函式。例如我們將物件變數儲存在另外一個數組中,而不是物件本身的成員變數

<?php

class MethodTest
{
    private $data = array();

    public function __set($name, $value) {
        $this->data[$name] = $value;
    }

    public function __get($name) {
        $object_name = null;
        if (array_key_exists($name, $this->data)) {
            $object_name = $this->data[$name];
        }
        return $object_name;
    }

    public function __isset($name) {
        return isset($this->data[$name]);
    }

    public function __unset($name) {
        unset($this->data[$name]);
    }
}
?>

__sleep()__wakeup()

當我們在執行serialize()unserialize()時,會先呼叫這兩個函式。例如我們在序列化一個物件時,這個物件有一個數據庫連結,想要在反序列化中恢復連結狀態,則可以通過重構這兩個函式來實現連結的恢復。serialize() 函式會檢查類中是否存在一個魔術方法 __sleep()。unserialize() 會檢查是否存在一個 __wakeup() 方法