PHP 魔法方法

2018-12-08 16:05 更新

Caution PHP 將所有以 __(兩個下劃線)開頭的類方法保留為魔術(shù)方法。所以在定義類方法時,除了上述魔術(shù)方法,建議不要以 __ 為前綴。

__sleep() 和 __wakeup()


public array __sleep ( void )

void __wakeup ( void )
serialize() 函數(shù)會檢查類中是否存在一個魔術(shù)方法 __sleep()。如果存在,該方法會先被調(diào)用,然后才執(zhí)行序列化操作。此功能可以用于清理對象,并返回一個包含對象中所有應(yīng)被序列化的變量名稱的數(shù)組。如果該方法未返回任何內(nèi)容,則 NULL 被序列化,并產(chǎn)生一個 E_NOTICE 級別的錯誤。

Note:

__sleep() 不能返回父類的私有成員的名字。這樣做會產(chǎn)生一個 E_NOTICE 級別的錯誤??梢杂?nbsp;Serializable 接口來替代。

__sleep() 方法常用于提交未提交的數(shù)據(jù),或類似的清理操作。同時,如果有一些很大的對象,但不需要全部保存,這個功能就很好用。
與之相反,unserialize() 會檢查是否存在一個 __wakeup() 方法。如果存在,則會先調(diào)用 __wakeup 方法,預(yù)先準(zhǔn)備對象需要的資源。
__wakeup() 經(jīng)常用在反序列化操作中,例如重新建立數(shù)據(jù)庫連接,或執(zhí)行其它初始化操作。

<?php
class 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();
    }
}
?>

__toString()


public string __toString ( void )
__toString() 方法用于一個類被當(dāng)成字符串時應(yīng)怎樣回應(yīng)。例如 echo $obj; 應(yīng)該顯示些什么。此方法必須返回一個字符串,否則將發(fā)出一條 E_RECOVERABLE_ERROR 級別的致命錯誤。
Warning : 不能在 __toString() 方法中拋出異常。這么做會導(dǎo)致致命錯誤。

實例

__toString():

<?php
// Declare a simple class
class TestClass
{
    public $foo;

    public function __construct($foo) 
    {
        $this->foo = $foo;
    }

    public function __toString() {
        return $this->foo;
    }
}

$class = new TestClass('Hello');
echo $class;
?>


運行實例 ?

需要指出的是在 PHP 5.2.0 之前,__toString() 方法只有在直接使用于 echo 或 print 時才能生效。PHP 5.2.0 之后,則可以在任何字符串環(huán)境生效(例如通過 printf(),使用 %s 修飾符),但不能用于非字符串環(huán)境(如使用 %d 修飾符)。自 PHP 5.2.0 起,如果將一個未定義 __toString() 方法的對象轉(zhuǎn)換為字符串,會產(chǎn)生 E_RECOVERABLE_ERROR 級別的錯誤。

__invoke()


mixed __invoke ([ $... ] )
當(dāng)嘗試以調(diào)用函數(shù)的方式調(diào)用一個對象時,__invoke() 方法會被自動調(diào)用。

Note:

本特性只在 PHP 5.3.0 及以上版本有效。

實例

__invoke():

<?php
class CallableClass 
{
    function __invoke($x) {
        var_dump($x);
    }
}
$obj = new CallableClass;
$obj(5);
var_dump(is_callable($obj));
?>


運行實例 ?


__set_state()


static object __set_state ( array $properties )

自 PHP 5.1.0 起當(dāng)調(diào)用 var_export() 導(dǎo)出類時,此靜態(tài) 方法會被調(diào)用。

本方法的唯一參數(shù)是一個數(shù)組,其中包含按 array('property' => value, ...) 格式排列的類屬性。


實例

__set_state():

<?php
class A
{
    public $var1;
    public $var2;

    public static function __set_state($an_array) // As of PHP 5.1.0
    {
        $obj = new A;
        $obj->var1 = $an_array['var1'];
        $obj->var2 = $an_array['var2'];
        return $obj;
    }
}

$a = new A;
$a->var1 = 5;
$a->var2 = 'foo';

eval('$b = ' . var_export($a, true) . ';'); // $b = A::__set_state(array(
                                            //    'var1' => 5,
                                            //    'var2' => 'foo',
                                            // ));
var_dump($b);
?>

運行實例 ?


__debugInfo()


array __debugInfo ( void )
當(dāng)轉(zhuǎn)儲對象以獲取應(yīng)顯示的屬性時,var_dump()調(diào)用此方法。 如果沒有在對象上定義方法,那么將顯示所有public,protected和private屬性。


實例

__debugInfo

<?php
class {
    private 
$prop;

    public function 
__construct($val) {
        
$this->prop $val;
    }

    public function 
__debugInfo() {
        return [
            
'propSquared' => $this->prop ** 2,
        ];
    }
}

var_dump(new C(42));
?>

運行實例 ?


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號