1.__construct() 當實例化一個對象的時候,這個對象的這個方法首先被調用。
代碼如下 復制代碼 class Test { function __construct() { echo "before"; } } $t = new Test();
輸出是:
start
構造器是一個魔術方法,當對象被實例化時它會被調用。在一個類聲明時它常常是第一件做的事但是沒得必要他也像其他任何方法在類中任何地方都可以聲明,構造器也能像其他方法樣繼承。如果我們想到以前繼承例子從介紹到oop,我們能添加構造方法到Animal 類中
1
class Animal{
public function __construct() {
$this->created = time();
$this->logfile_handle = fopen('/tmp/log.txt', 'w');
}
}
現在我們創建一個類來繼承Animal類 - Penguin類!不添加任何屬性和方法在Penguin類中,我們能申明並定義它繼承自
代碼如下 復制代碼Animal類,如:
class Penguin extends Animal {
}
$tux = new Penguin;
echo $tux->created;
我們知道php5對象模型 和類名相同的函數是類的構造函數,那麼如果我們同時定義構造函數和__construct()方法的話,php5會默認調用構造函數而不會調用__construct()函數,所以__construct()作為類的默認的構造函數
2.__destruct() 當刪除一個對象或對象操作終止的時候,調用該方法。
Java代碼
我們就可以在對象操作結束的時候進行釋放資源之類的操作
3.__get() 當試圖讀取一個並不存在的屬性的時候被調用。
如果試圖讀取一個對象並不存在的屬性的時候,PHP就會給出錯誤信息。如果在類裡添加__get方法,並且我們可以用這個函數實現類似java中反射的各種操作。
代碼如下 復制代碼 class Test { public function __get($key) { echo $key . " 不存在"; } } $t = new Test(); echo $t->name; 就會輸出:name 不存在
例子
代碼如下 復制代碼class Penguin extends Animal {
public function __construct($id) {
$this->getPenguinFromDb($id);
}
public function getPenguinFromDb($id) {
}
}
4.__set() 當試圖向一個並不存在的屬性寫入值的時候被調用。
代碼如下 復制代碼
class Test { public function __set($key,$value) { echo '對'.$key . "附值".$value; } } $t = new Test(); $t->name = "aninggo"; 就會輸出:對 name 附值 aninggo
class Test { public function __set($key,$value) { echo '對'.$key . "附值".$value; } } $t = new Test(); $t->name = "aninggo"; 就會輸出:對 name 附值 aninggo
5.__call() 當試圖調用一個對象並不存在的方法時,調用該方法。
class Test { public function __call($Key, $Args) { echo "您要調用的 {$Key} 方法不存在。你傳入的參數是:" . print_r($Args, true); } } $t = new Test(); $t->getName(aning,go);
class Test { public function __call($Key, $Args) { echo "您要調用的 {$Key} 方法不存在。你傳入的參數是:" . print_r($Args, true); } } $t = new Test(); $t->getName(aning,go);
程序將會輸出:
您要調用的 getName 方法不存在。參數是:Array
(
[0] => aning
[1] => go
)
您要調用的 getName 方法不存在。參數是:Array
(
[0] => aning
[1] => go
)
6.__toString() 當打印一個對象的時候被調用
這個方法類似於java的toString方法,當我們直接打印對象的時候回調用這個函數
代碼如下 復制代碼
class Penguin {
public function __construct($name) {
$this->species = 'Penguin';
$this->name = $name;
}
public function __toString() {
return $this->name . " (" . $this->species . ")n";
}
}
在適當的位置,輸出該對象通過調用echo輸出它,如:
代碼如下 復制代碼$tux = new Penguin('tux');
echo $tux;
7.__clone()
我們看過一個使用clone關鍵字的例子,在我的介紹從入門到oop的第二部分,創建對象的副本,而不是有兩個變量指向同一個實際的數據。在一個類中重寫此方法,我們可以觀察發生了什麼當在對象上使用clone關鍵字時,。雖然這是不是我們每一天能遇到的,一個漂亮的用例是創建一個真正的單例模式通過添加private訪問修飾符給這個方法。
代碼如下 復制代碼class Test { public function __clone() { echo "我被復制了!"; } }$t = new Test(); $t1 = clone $t;程序輸出:我被克隆了!
__sleep
__sleep()方法會被調用當對象被序列化後,並允許你處理序列化。這有各種各樣的程序,一個很好的例子如果一個對象包含某種類型的指針,例如文件句柄或引用另一個對象。當對象被序列化然後解序列化,這些引用類型是無用的,因為這些類型的引用的目標可能不再存在或有效。因此,最好是來取消這些信息在存儲它們之前。
__wakeup
__wakeup()是與__sleep()方法相反的,允許您更改對象解序列化的行為。和__sleep()一起使用,可以用來恢復被刪除的句柄和對象當對象被序列化時。一個很好的例子程序是數據庫句柄被取消設置當該項被序列化,然後恢復到當前配置中設置項目時,解序列化一個數據庫句柄。
__autoload()方法可
比如我們將上面的那個Person類所在的文件定義為 Person_class.php ,
再新建一個php文件 test.php,編輯內容:
這樣執行該test.php頁面就不會出現錯誤了。
php魔術方法一般在什麼情況下需要使用
舉個簡單的例子,當類裡面沒有屬性$name; 但是你不小心訪問這個屬性,這個時候就會出錯。但是讓你可以設置魔術方法__get($name){ return $name . "不存在"};就會自動調用__get($name);這樣程序就會不因為你訪問了一個不存在的屬性報錯而中斷執行
補充下 __get($v) 訪問未定義的屬性時調用,
__set($v) ?未定義的屬性賦值時調用,
__isset($v)對未定義的屬性使用isset()函數時調用,
__unset($v)和isset($v)類似
__call($method)訪問未定義的方法是被調用