__set和__get方法

__set和__get是兩個比較重要的魔術方法,如下面代碼所示。

<?php
class Account
{
    private $user = 1;
    private $pwd = 2;
}

$a = new Account();
echo $a->user;
$a->name = 5;
echo $a->name;
echo $a->big;

運行這段代碼會怎麼樣呢?結果報錯如下:

PHP Fatal error:  Cannot access private property Account::$user in F:\WWW\demo\2017\1\27\1.php on line 9

所報錯誤大致是說,不能訪問Account對象的私有屬性user。在上面代碼中的Account類中增加以下代碼,其中使用了__set和__get魔術方法。

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

    public function __get($name)
    {
        if(isset($this->$name)){
            return $this->$name;
        }
        return null;
    }

再次運行,看到正常輸出,沒有報錯。在類裏以鏈各個下劃線開頭的方法都屬於魔術方法(除非是你自定義的),它們是PHP種的內置方法,有特殊含義。手冊裏把這個兩個方法歸到重載。

PHP的重載和Java等語言的重載不同。Java裏,重載是指一個類中可以定義參數列表不同但名字相同的多個方法。比如Java也有構造方法,Java允許有多個構造函數,只要保證方法簽名不一樣就行;而PHP則在一個類中只允許有一個構造函數。

PHP提供的“重載”指動態地“創建”類屬性和方法。因此,__set和__get方法被歸到重載裏。

這裏可以直觀看到,若類中定義了__set和__get這一對魔術方法,那麼當給對象屬性賦值或者取值時,即使這個屬性不存在,也不會報錯,一定程度上增加了程序的健壯性。

我們注意到,在Account類裏,user屬性的訪問權限是私有的,私有的屬性意味着這個屬性是類的“私有財產”,只能在類內部對其進行操作。如果沒有__set這個魔術方法,直接在類的外部對屬性進行賦值操作是會報錯的,只能通過在類中定義一個public的方法,然後在類外調用這個公開的方法進行屬性讀寫操作。

現在有了這兩個魔術方法,是不是對私有屬性的操作變得更方便了呢?實際上,並沒有什麼奇怪的,因爲這兩個方法本身就是public的。它們和在對外的pblic方法中的操作private屬性的原理一樣。只不過這對魔術方法使其操作更簡單,不需要顯示地調用一個public的方法,因爲這對魔術方法在操作類變量時是自動調用的。當然,也可以把類屬性定義成public的,這樣就可以隨意在類的外部進行讀寫。不過,如果只是爲了方便,類屬性在任意時候都定義成public權限顯然是不合適的,也不符合面向對象的設計思想

發佈了58 篇原創文章 · 獲贊 54 · 訪問量 14萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章