PHP中的魔術方法

2021-07-31 05:41:04 字數 4972 閱讀 3523

概述

在物件導向程式設計中,php提供了一系列的魔術方法,這些魔術方法為程式設計提供了很多便利。php中的魔術方法通常以__(兩個下劃線)開始,並且不需要顯示的呼叫而是由某種特定的條件出發。這篇文章簡單總結了php中提供的魔術方法。

開始之前

在總結php的魔術方法之前先來定義兩個類,以便後邊示例使用:

複製**

**如下:

<?php

class device

protected function disconnect() }

class battery

elseif($charge > 100)

$this->charge = $charge; }

}?>

device類有四個成員屬性和兩個成員方法。battery類有乙個成員屬性和乙個成員方法。

建構函式和析構函式

建構函式和析構函式分別在物件建立和銷毀時被呼叫。物件被「銷毀」是指不存在任何對該物件的引用,比如引用該物件的變數被刪除(unset)、重新賦值或指令碼執行結束,都會呼叫析構函式。

__construct()

__construct()建構函式是目前為止最經常使用的函式。在建立物件時,可以在建構函式中做一些初始化工作。可以為建構函式定義任意多個引數,只要在例項化時傳入對應個數的引數即可。建構函式中出現的任何異常都會阻止物件的建立。

複製**

**如下:

class device }

上面的示例**中,device類的建構函式為成員屬性賦值並且呼叫了connect()方法。

複製**

**如下:

將建構函式宣告為私有方法,可以防止在類外部建立物件,這在單利模式中經常使用。

__desctruct()

析構函式通常在物件被銷毀時呼叫,析構函式不接收任何引數。經常在析構函式中執行一些清理工作,比如關閉資料庫連線等。

屬性過載(property overloading)

有一點需要注意的是:php中的」過載」與其他大多數語言的過載不是太一樣,雖然都實現了相同的功能。

屬性過載涉及到的兩個魔術方法主要是用來處理屬性訪問,定義了當我們嘗試訪問乙個不存在(或不可訪問)的屬性時會發生什麼。

__get()

魔術方法__get()在我們嘗試訪問乙個不存在的屬性時會被呼叫。它接收乙個引數,該引數表示訪問屬性的名字,並且將該屬性的值返回。在上面的device類裡,有乙個data屬性,該屬性就在這裡就起了作用,如下面得**:

複製**

**如下:

class device

return null; }

}該魔術方法最常用的地方就是通過建立乙個「唯讀」的屬性來擴充套件訪問控制。在上面的battery類中,有乙個私有屬性$charge,我們可以通過__get()魔術方法將該屬性擴充套件為在類外部可讀但不能修改。**如下:

複製**

**如下:

class battery

return null; }

}__set()

__set()魔術方法在我們嘗試修改乙個不可訪問的屬性時會被呼叫,它接收兩個引數,乙個表示屬性的名字,乙個表示屬性的值。示例**如下:

複製**

**如下:

class device }

__isset()

__isset()魔術方法在對乙個不可訪問的屬性呼叫isset()方法時會被呼叫,它接收乙個引數,表示屬性的名字。它應該返回乙個布林值,用來表示該屬性是否存在。**如下:

複製**

**如下:

class device }

__unset()

__unset()魔術方法在呼叫unset()函式銷毀乙個不能訪問的屬性時會被呼叫,它接收乙個引數,表述屬性的名字。

物件轉換為字串

有時候我們需要將物件以字串的形式表現出來。如果我們直接列印乙個物件,那麼程式將會輸出乙個錯誤資訊:php catchable fatal error: object of class device could not be converted to string

__tostring()

__tostring()在我們將物件當作字串一樣使用時會被呼叫,它不接收任何引數。該方法允許我們定義物件的表現形式。**如下:

複製**

**如下:

class device

... }

__set_state()(php 5.1)

靜態魔術方法__set_state(),在我們使用var_export()函式輸出物件時會呼叫該方法。var_export()函式用來將php變數轉換為php**,它接收乙個包含物件屬性值的關聯陣列作為引數。示例**如下:

複製**

**如下:

class battery

//... }

轉殖物件

預設的,物件都是按引用傳值的。因此,在將乙個物件賦值給另乙個變數時,只是建立了指向該物件的乙個引用,並沒有複製該物件。為了實現真正得複製乙個物件,我們需要使用clone關鍵字。

這種「按引用傳遞」的策略同樣適用於包含在物件內部的物件。即使我們轉殖了乙個物件,在物件內部的任何物件都不會被轉殖,因此最終的結果是兩個物件共享了同乙個內部物件。示例**如下:

複製**

**如下:

$device = new device(new battery(), 'imagic');

$device2 = clone $device;

$device->battery->setcharge(65);

echo $device2->battery->charge;

// 65

__clone()

__clone()魔術方法__clone()可以解決上面的問題。當對乙個物件使用clone關鍵字時,該魔術方法會被呼叫。在這個魔術方法裡,我們可以實現任何子物件的轉殖,**如下:

複製**

**如下:

class device

... }

物件序列化

序列化是講任意資料轉換為字串格式的過程。序列化通常用來將整個物件存入資料庫或寫入檔案中。當反序列化儲存的資料時,我們可以得到序列化之前的物件。但是,並不是所有得資料都可以被序列化,比如資料庫連線。幸運的是,有乙個魔術方法可以幫我們解決這個問題。

__sleep()

魔術方法__sleep()在對乙個物件序列化時(呼叫serialize())會被呼叫。它不接收任何引數,而且應該返回乙個包含所有應該被序列化的屬性的陣列。在該魔術方法中,也可以執行一些其他操作。

有一點要注意的是,不要再該函式中進行任何的析構操作,因為這可能會影響正在執行的物件。

示例**如下:

複製**

**如下:

class device

//... }

__wakeup()

魔術方法__wakeup()在對儲存的物件反序列化時會被呼叫。它不接收任何引數,也沒有任何返回值。可以用它來處理在序列化時丟失的資料庫連線或資源。**如下:

複製**

**如下:

class device

//... }

方法過載

php還有兩個與成員方法相關的魔術方法__call()和__callstatic(),這兩個魔術方法類似於屬性過載方法。

__call()

魔術方法__call()在呼叫不存在或不可訪問的方法時會被呼叫。它接收兩個引數,乙個是呼叫的方法的名字,乙個是包含函式引數的陣列。我們可以使用這種方法呼叫子物件中得同名函式。

在這個例子中,要注意函式call_user_func_array(),這個函式允許我們動態呼叫乙個命名的函式。

示例**如下:

複製**

**如下:

class device

return null; }

//... }

__callstatic()

魔術方法__callstatic()與__call()的功能一樣,唯一不同的是,該方法在嘗試訪問乙個不存在或不可訪問的靜態方法時會被呼叫。示例**如下:

複製**

**如下:

class device

return null; }

//... }

將物件作為函式

有時候我們會需要將物件作為函式使用。將物件作為函式使用,就像我們使用其他普通的函式一樣,可以傳參。

__invoke()(php 5.3)

魔術方法__invoke()在嘗試將物件作為函式使用時會被呼叫。在該方法中定義的任何引數,都將被作為函式的引數。示例**如下:

複製**

**如下:

class device

//... }

$device = new device(new battery(), 'imagic');

$device('test');

// equiv to $device->__invoke('test')

// outputs: test

其他:__autoload()

__autoload()方法並不是乙個魔術方法,但是這個方法非常有用。但是,對著php版本的更新,該函式已經不建議使用,取而代之的是spl_auto_register()函式。

PHP中的魔術方法

php 將所有以 兩個下劃線 開頭的類方法保留為魔術方法。因此,在定義類方法時,除了下述魔術方法外,建議不要以 為字首。construct 構造方法或建構函式 具有建構函式的類會在每次建立新物件時,先呼叫此方法。因此,非常適合在使用物件之前做一些初始化操作。注意 如果子類中定義了建構函式則不會隱式呼...

PHP 中的魔術方法

1.construct 此為構造方法,是物件建立完成後第乙個被物件自動呼叫的方法,通常使用該方法完成一些物件的初始化工作。class person function say function run person1 new person 張三 男 20 person2 new person 李四 女...

php中的魔術方法

參考文件 a.對不可訪問的物件賦值的時候 set b.讀取不可訪問的物件的時候 get c.對可以訪問的屬性呼叫 isset empty isset d.對不可訪問的物件調 unset unset e.構造方法 construct f.乙個物件被當成乙個字串返回的時候應該返回什麼 tostring ...