php魔術方法簡介

2020-07-16 10:05:57

前面的話

  php在物件導向部分有很多相關的魔術方法,這些方法為物件導向實現提供了便利,本文將詳細介紹魔術方法

構造方法

  大多數類都有一種稱為建構函式的特殊方法。當建立一個物件時,它將自動呼叫建構函式,通常用它執行一些有用的初始化任務

  建構函式的宣告與其它操作的宣告一樣,只是其名稱必須是兩個下劃線__construct( )。這是PHP5中的變化;PHP4的版本中,建構函式的名稱必須與類名相同。為了向下相容,如果一個類中沒有名為__construct( )的方法,PHP將搜尋一個與類名相同的方法

void __construct ([ mixed $args [, $... ]] )

  如果子類中定義了建構函式則不會隱式呼叫其父類別的建構函式。要執行父類別的建構函式,需要在子類別建構函式中呼叫 parent::__construct()。如果子類沒有定義建構函式則會如同一個普通的類方法一樣從父類別繼承(假如沒有被定義為 private 的話)

<?phpclass BaseClass {
   function __construct() {
       print "In BaseClass constructor
";
   }
}class SubClass extends BaseClass {
   function __construct() {
       parent::__construct();       print "In SubClass constructor
";
   }
}

解構方法

  與構造方法相對的就是解構方法。解構方法是PHP5新新增的內容,在PHP4中沒有解構方法。解構方法是在物件被銷毀之前自動呼叫的方法,主要執行一些特定的操作,例如關閉檔案,釋放結果集等

  與構造方法類似,一個類的解構方法名稱必須是兩個下劃線 __destruct( )。解構函式不能帶有任何引數

<?phpclass MyDestructableClass {
   function __construct() {
       print "In constructor
";       $this->name = "MyDestructableClass";
   }   function __destruct() {
       print "Destroying " . $this->name . "
";
   }
}//In constructor Destroying MyDestructableClass$obj = new MyDestructableClass();?>

不可存取屬性

get()

  讀取不可存取屬性(protected、private)時,__get()會被呼叫,並將屬性名以第一個引數(string)傳進此方法中

public mixed __get ( string $name )

<?phpclass demo{
    protected $protected = 1;    public $public = 2;    private $private = 3;    function __get($name){
        echo "111{$name}111<br>";
    }
}$d1 = new demo;$d1->protected;//111protected111$d1->public;$d1->private;//111private111?>

set()

  在給不可存取屬性(protected、private)賦值時,__set() 會被呼叫,並將屬性名以第一個引數(string),值作為第二引數(mixed)傳進此方法中

public void __set ( string $name , mixed $value )
<?phpclass demo{
    protected $protected = 1;    public $public = 2;    private $private = 3;    function __set($name,$value){
        echo "0{$name}0{$value}<br>";
    }
}

isset()

  當對不可存取屬性(protected、private)呼叫 isset() 或 empty() 時,__isset() 會被呼叫

public bool __isset ( string $name )
<?phpclass demo{
    protected $protected = 1;    public $public = 2;    private $private = 3;    function __isset($name){
        echo "0{$name}0<br>";
    }
}

unset()

  當對不可存取屬性(protected、private)呼叫unset()時,__unset()會被呼叫

public void __unset ( string $name )

<?phpclass demo{
    protected $protected = 1;    public $public = 2;    private $private = 3;    function __unset($name){
        echo "0{$name}0<br>";
    }
}

物件複製

clone()

  在物件克隆時會自動呼叫clone()方法,這方法不需要任何引數,可以通過該方法對克隆後的副本重新初始化

  clone()方法會自動包含this和that兩個物件的參照,this是副本物件的參照,that是原本物件的參照

<?php
    class Person{
        private $name;        private $sex;        private $age;        function __construct($name="",$sex="",$age=1){
            $this->name= $name;            $this->sex = $sex;            $this->age = $age;
        }        function __clone(){
            $this->name = $this->name."的副本";
        }        function say(){
            echo "我的名字:" .$this->name.",性別:".$this->sex.",年齡:".$this->age."<br>";
        }
    }

字串

toString()

  __toString()方法用於一個類被當成字串時應怎樣回應,它是快速獲取物件的字串表示的最便捷的方式,是直接輸出物件參照時自動呼叫的方法

<?phpclass TestClass{
public $foo; public function __construct($foo)
{
$this->foo = $foo;
} public function __toString() {
return $this->foo;
}
}$class = new TestClass('Hello');echo $class;//Hello?>

物件不存在

call()

  在物件中呼叫一個不可存取方法時,__call()會被呼叫

callStatic()

  在靜態上下文中呼叫一個不可存取方法時,__callStatic()會被呼叫

<?phpclass MethodTest {
    public function __call($name, $arguments) 
    {
        echo "Calling object method '$name' "
             . implode(', ', $arguments). "
";
    }    public static function __callStatic($name, $arguments) 
    {
        echo "Calling static method '$name' "
             . implode(', ', $arguments). "
";
    }
}

自動載入類

autoload()

  在PHP5中,可以定義一個__autoload()函數,它會在試圖使用尚未被定義的類時自動呼叫。通過呼叫此函數,指令碼引擎在PHP出錯失敗前有了最後一個機會載入所需的類

<?phpfunction __autoload($class_name) {
    require_once $class_name . '.php';
}

序列化

sleep()

  在呼叫serialize()函數將物件序列化時,檢查類中是否存在一個魔術方法 __sleep()。如果存在,該方法會先被呼叫,然後才執行序列化操作。此功能可以用於清理物件,並返回一個包含物件中所有應被序列化的變數名稱的陣列。如果該方法未返回任何內容,則 NULL 被序列化,並產生一個 E_NOTICE 級別的錯誤

  __sleep()函數不需要接受任何引數,但需要返回一個陣列,在陣列中包含需要序列化的屬性。未被包含在陣列中的屬性將在序列化時被忽略。如果沒有在類中宣告__sleep()方法,物件中的所有屬性都將被序列化

wakeup()

  在呼叫unserialize()函數將物件反序列化物件時,則會自動呼叫物件中的__wakeup()方法,用來在二進位制串重新組成一個物件時,為新物件中的成員屬性重新初始化

  wakeup()經常用在反序列化操作中,例如重新建立資料庫連線,或執行其它初始化操作

<?phpclass Connection {
    protected $link;    private $server, $username, $password, $db;  
    public function __construct($server, $username, $password, $db)
    {
        $this->server = $server;        $this->username = $username;        $this->password = $password;        $this->db = $db;        $this->connect();
    }    private function connect()
    {
        $this->link = mysql_connect($this->server, $this->username, $this->password);        mysql_select_db($this->db, $this->link);
    }    public function __sleep()
    {
        return array('server', 'username', 'password', 'db');
    }    public function __wakeup()
    {
        $this->connect();
    }
}?>

函數呼叫

invoke()

  當嘗試以呼叫函數的方式呼叫一個物件時,__invoke()方法會被自動呼叫

<?phpclass CallableClass {
    function __invoke($x) {
        var_dump($x);
    }
}

【補充】

set_state()

  當呼叫var_export()匯出類時,set_state()方法會被呼叫,本方法的唯一引數是一個陣列,其中包含按 array('property' => value, ...) 格式排列的類屬性

  [注意]var_export()返回關於傳遞給該函數的變數的結構資訊,它和var_dump()類似,不同的是其返回的表示是合法的PHP程式碼,也就是說,var_export返回的程式碼,可以直接當作php程式碼賦給一個變數。 而這個變數就會取得和被var_export一樣的型別的值

<?phpclass A{
public $var1; public $var2; public static function __set_state($an_array)
{
$obj = new A; $obj->var1 = $an_array['var1']; $obj->var2 = $an_array['var2']; return $obj;
}
}

相關參考:TW511.COM

以上就是php魔術方法簡介的詳細內容,更多請關注TW511.COM其它相關文章!