首頁  >  文章  >  後端開發  >  php中重載與魔術方法的範例詳解

php中重載與魔術方法的範例詳解

黄舟
黄舟原創
2017-11-02 09:16:101218瀏覽

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

作用:利用模式方法可以輕鬆實作PHP物件導向中重載(Overloading即動態建立類別屬性與方法

其實很多部落客已經寫過這些方法了、、、但是我還是要說一遍。 。誰叫你來聽了呢,碼這麼多字也不容易看完再走吧!

1.construct,destruct
 constuct建構物件的時被呼叫;
 destruct明確銷毀物件或腳本結束時被呼叫; 

class Foo {    
private $name;    
private $link;    
public function construct($name) {        
$this->name = $name;
    }    
    public function destruct() {        
    echo 'Destroying: ', $this->name, PHP_EOL;//PHP_EOL代表php的换行符    }
}

#打住,先安麗一波重載的定義及使用方法:

#定義:PHP所提供的"重載" (overloading)是指動態地"建立"類別屬性和方法。 (我們是透過魔術方法(magic methods)來實現的)

#作用:當呼叫目前環境下未定義或不可見的類別屬性或方法時,重載方法會被呼叫。後面將使用"不可訪問屬性(inaccessible properties)"和"不可訪問方法(inaccessible methods)"來稱呼這些未定義或不可見的類別屬性或方法。

注意:所有的重載方法都必須宣告為 public

 2.get、set、isset、unset、call、callStatic  //為啥放一起呢?


 set當給不可訪問或不存在屬性賦值時被調用
 get讀取不可訪問或不存在屬性時被調用

isset對不可訪問或不存在的屬性在呼叫isset()或empty()時被呼叫
 unset對不可存取或不存在的屬性進行unset時被呼叫

call呼叫不可存取或不存在的方法時被呼叫
 callStatic呼叫不可存取或不存在的靜態方法時被呼叫

Example #1 使用 get(),set(),isset() 和 unset() 進行屬性重載

<?php
class PropertyTest {
     /**  被重载的数据保存在此  */
    private $data = array();

 
     /**  重载不能被用在已经定义的属性  */
    public $declared = 1;

     /**  只有从类外部访问这个属性时,重载才会发生 */
    private $hidden = 2;

    public function set($name, $value) 
    {
        echo "Setting &#39;$name&#39; to &#39;$value&#39;\n";
        $this->data[$name] = $value;
    }


    public function get($name) 
    {
        echo "Getting &#39;$name&#39;\n";
        if (array_key_exists($name, $this->data)) {
            return $this->data[$name];
        }

        $trace = debug_backtrace();
        trigger_error(
            &#39;Undefined property via get(): &#39; . $name .
            &#39; in &#39; . $trace[0][&#39;file&#39;] .
            &#39; on line &#39; . $trace[0][&#39;line&#39;],
            E_USER_NOTICE);
        return null;
    }



    /**  PHP 5.1.0之后版本 */
    public function isset($name) 
    {
        echo "Is &#39;$name&#39; set?\n";
        return isset($this->data[$name]);
    }

    /**  PHP 5.1.0之后版本 */
    public function unset($name) 
    {
        echo "Unsetting &#39;$name&#39;\n";
        unset($this->data[$name]);
    }

    /**  非魔术方法  */
    public function getHidden() 
    {
        return $this->hidden;
    }
}


echo "<pre class="brush:php;toolbar:false">\n";

$obj = new PropertyTest;

$obj->a = 1;
echo $obj->a . "\n\n";

var_dump(isset($obj->a));
unset($obj->a);
var_dump(isset($obj->a));
echo "\n";

echo $obj->declared . "\n\n";

echo "Let&#39;s experiment with the private property named &#39;hidden&#39;:\n";
echo "Privates are visible inside the class, so get() not used...\n";
echo $obj->getHidden() . "\n";
echo "Privates not visible outside of class, so get() is used...\n";
echo $obj->hidden . "\n";
?>

看完了嗎?好好看!

5.sleep,wakeup
sleep當使用serialize時被調用,當你不需要保存大物件的所有資料時很有用

wakeup當使用unserialize時被調用,可用來做些物件的初始化操作

<?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(&#39;server&#39;, &#39;username&#39;, &#39;password&#39;, &#39;db&#39;);
    }
    
    public function wakeup()
    {
        $this->connect();
    }
}
?>

6.clone

 進行物件clone時被調用,用來調整物件的複製行為

<?php
class SubObject
{
    static $instances = 0;
    public $instance;

    public function construct() {
        $this->instance = ++self::$instances;
    }

    public function clone() {
        $this->instance = ++self::$instances;
    }
}

class MyCloneable
{
    public $object1;
    public $object2;

    function clone()
    {
      
        // 强制复制一份this->object, 否则仍然指向同一个对象
        $this->object1 = clone $this->object1;
    }
}

$obj = new MyCloneable();

$obj->object1 = new SubObject();
$obj->object2 = new SubObject();

$obj2 = clone $obj;


print("Original Object:\n");
print_r($obj);

print("Cloned Object:\n");
print_r($obj2);

?>

7.toString
 當一個類別轉換成字串時被呼叫

<?php
class SubObject
{
    static $instances = 0;
    public $instance;

    public function construct() {
        $this->instance = ++self::$instances;
    }

    public function clone() {
        $this->instance = ++self::$instances;
    }
}

class MyCloneable
{
    public $object1;
    public $object2;

    function clone()
    {
      
        // 强制复制一份this->object, 否则仍然指向同一个对象
        $this->object1 = clone $this->object1;
    }
}

$obj = new MyCloneable();

$obj->object1 = new SubObject();
$obj->object2 = new SubObject();

$obj2 = clone $obj;


print("Original Object:\n");
print_r($obj);

print("Cloned Object:\n");
print_r($obj2);

?>

8.set_state
#  當呼叫var_export()匯出類別時,此靜態方法被呼叫。用set_state的回傳值做為var_export的回傳值。

<?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[&#39;var1&#39;];
        $obj->var2 = $an_array[&#39;var2&#39;];
        return $obj;
    }
}

$a = new A;
$a->var1 = 5;
$a->var2 = &#39;foo&#39;;

eval(&#39;$b = &#39; . var_export($a, true) . &#39;;&#39;); // $b = A::set_state(array(
                          //    &#39;var1&#39; => 5,
                          //    &#39;var2&#39; => &#39;foo&#39;,
                          // ));
var_dump($b);
?>

以上是php中重載與魔術方法的範例詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn