方法名 | 描述 |
__construct() | 類的構造函數 |
__destruct() | 類的析構函數 |
__call($funName, $arguments) | 當調用一個(gè)未定義或不可(kě)達方法時, __call() 方法答費将被調用。 |
__callStatic($funName, $arguments) | 當調用一個(gè)未定義或不可(kě)達的靜态方法討視時, __callStatic() 方法将被調用知得。 |
__get($propertyName) | 當獲取一個(gè)類的成員變量時, __get() 方法将老著被調用。 |
__set($property, $valu湖畫e) | 當賦值一個(gè)類的成員變量時, __set() 方法将被調離站用。 |
__isset($content) | 當調用 isset() 或 empty() 對一個(gè)未定義或不可(媽窗kě)達的成員賦值時, __isset() 方法将被調用裡微。 |
__unset($content) | 當調用 reset() 對一個(gè)未定義或不可(kě)信問達的成員更新時, __unset() 方法将被調用。 |
__sleep() | 當執行序列化 serialize() 時,__sleep() 方法将首電中先被調用。 |
__wakeup() | 當執行反序列化 deserialization()黃醫 時, __wakeup() 方法将首先被調用。 |
__toString() | 當使用 echo 方法直接輸出顯示對象時,__toString() 方法舞能首先被調用。 |
__invoke() | 使用調用函數(function)訪問(wèn)一個(gè)對象時, __西數invoke() 方法将首先被調用。 |
__set_state($an_array) | 當調用 var_export() 方法時,__農還set_state() 方法将被調用。 |
__clone() | 當對象被複制賦值時,__clone() 方法将被調用。 |
__autoload($className) | 試圖載入一個(gè)未定義的類時調用。 |
__debugInfo() | 輸出 debug 信息。 |
範例
下(xià)面讓我們以實例的形式向大家講解下(xià)這幾個(gè)魔術筆有(shù)方法時如(rú)何使用的。
一、 __construct(),類的構造函數
php中(zhōng)構造方法是對象創建完成後第一個(gè)被對有花象自動(dòng)調用的方法。在每個(gè)類中(zhōng)都有一個廠姐(gè)構造方法,如(rú)果沒有顯示地聲明它,那麼類要影中(zhōng)都會默認存在一個(gè)沒有參又從數且内容為空的構造方法。
1、 構造方法的作用
通(tōng)常構造方法被用來執行一些有用的初始化都秒任務,如(rú)對成員屬性在創建對象時賦予初始值。
2、 構造方法的在類中(zhōng)的聲明格式
function __constrct([參數列表]友可){
方法體 //通(tōng)件空常用來對成員屬性進行初始化賦值
}
3、 在類中(zhōng)聲明構造方法需要注意的事項
1、在同一個(gè)類中(zhōng)隻外時能聲明一個(gè)構造方法,原因是,PHP不支持構造函北下數重載。
2、構造方法名稱是以兩個(gè)下(xià)畫線開始的__con場物struct()
下(xià)面是它的例子(zǐ):
<?php
class Person見身
{ &nbs男日p; &n理鐵bsp; 外匠 子你 &nbs銀是p;  東學; 到和 &劇報nbsp; &n西麗bsp;
 校拿; public $na筆做me;
&音費nbsp; public $紅唱age; &nb湖舞sp;
 通兒; public $sex; &n如我bsp;
&n購靜bsp; &nbs店請p; 術紅 &n不年bsp;  化拿; &nb煙習sp; &n紙國bsp; &場近nbsp;
工那 /**
妹但* 顯示聲明一個(gè)構造方法且帶參數
用校 */  分文; &nb土章sp; &n中議bsp; 做男 &唱間nbsp; 如校 &nbs分房p; &術內nbsp;  志商; &n上照bsp;
&n藍討bsp; public function __construct($name=是筆"", $sex="男購機(nán)", $age=22)
{ &n們亮bsp;
&nbs術做p; $thi電拿s->name = $name;
他什 $this->se你工x = $sex;
&nb技自sp; $this->age 長好= $age;
}
/**
 機雨; * say 方法
*/
但內public function say()
時話 {
&nb門亮sp; echo "我叫:" . $this-&g費鐵t;name . ",性别:" . $this->藍地sex . ",年齡:" 為嗎. $this->age;
外拍 }
&nb山腦sp; &n和信bsp; &n水什bsp; &nbs能到p; &n機計bsp; &nbs跳遠p;  明吧; &nbs快船p; &nb票拿sp; &nbs道吧p; &nb就資sp;
}
創建對象$Person1且不帶任參數
$Person1 = new Person();師新
echo $Person1->say(); /煙錢/輸出:我叫:,性别:男(nán),年齡:27
創建對象$Person2且帶參數“小明”
$Person2 = new Person("小黃校明");
echo $Person2->say(); //輸出:我坐湖叫:張三,性别:男(nán),年齡:27
創建對象$Person3且帶三個(gè)參數唱兒
$Person3 = new Person("李四&歌林quot;,"男(nán)",25);
echo $Person3->say(); 技麗//輸出:我叫:李四,性别:男(nán),年齡:25
二、__destruct(),類的析構函數
通(tōng)過上面的講解,現在我們已經知道了什麼叫構造方法。那麼與構造短弟方法對應的就是析構方法。
析構方法允許在銷毀一個(gè)類之前執行的一些花算操作或完成一些功能,比如(rú)說關(guān)閉文(wén)件、釋放結果集大工等。
析構方法是PHP5才引進的新内容。
析造方法的聲明格式與構造方法 __construct() 比較相內類似,也是以兩個(gè)下(xià)劃線開始的方法 __destr我愛uct() ,這種析構方法名稱也是固定的。
1、 析構方法的聲明格式
function __destruct()
{
//方法體
}
注意:析構函數不能帶有任何參數。
2、 析構方法的作用
一般來說,析構方法在PHP中(zhōng)并不件很是很常用,它屬類中(zhōng)可(kě)選擇的一部分,通(tōng)常用件老來完成一些在對象銷毀前的清理任務。
舉例演示,如(rú)下(xià):
<?php
class Person{  兒呢;
&n火服bsp; &師藍nbsp;  吧了;  廠這; &nb討輛sp; &nbs雜事p;  離相;
public $name; 笑資; 海麗
public $age; 懂懂
public $sex; 人些
影腦 &報藍nbsp; &nbs購兒p; &體器nbsp; &nbs呢為p; &nb但議sp; &知快nbsp;
public func讀黃tion __construct($name="城習", $sex="男(n跳自án)", $age=22)
{  匠火;
 黃習; $this->name = $name;
去校 $this->sex&n農醫bsp; = $sex;
&n藍飛bsp; $this->age = $age;
}
/**
* say 說話方法
電舊*/
public function 街時say()
{
echo "如章我叫:".$this->name.個子",性别:".$this->sex.&qu小但ot;,年齡:".$this->age爸些;
} 上理
/**
* 聲明一錢呢個(gè)析構方法
*/
public function __dest街什ruct()
{
 聽火; echo "我覺得我還可(kě)以再搶救件雪一下(xià),我的名字叫".$照師this->name;
}
}
$Person = new Person("小明&quo就花t;);
unset($Person); //銷毀上面創建的對象$Perso地好n
上面的程序運行時輸出:
我覺得我還可(kě)以再搶救一下(xià),我的名字叫小明
三、 __call(),在對象中(zhōng)調用一個(gè)不可(kě)和上訪問(wèn)方法時調用。
該方法有兩個(gè)參數,第一個(gè)參數 $funct空讀ion_name 會自動(dòng)接收不存在的方法名,議近第二個(gè) $arguments 則以間相數組的方式接收不存在方法的多個(gè)參數體頻。
1、 __call() 方法的格式:
function __call(string $fu明你nction_name, array $argumen紙校ts)
{
// 方法體
}
2、 __call() 方法的作用:
為了避免當調用的方法不存在時産生錯誤,而意外的導緻程序中(zhōng)開區止,可(kě)以使用 __call() 方法來避免。
該方法在調用的方法不存在時會自動(dòn森廠g)調用,程序仍會繼續執行下(xià)去。
請參考如(rú)下(xià)代碼:
<?php
class Person
{ &n村問bsp;  制吧;  開懂;
function say(高從)
{ &nb那火sp;
 近美;  說視; &nbs劇好p; &火術nbsp;
&nb土地sp;echo "Hello, worl綠一d!
";
} 去拍
/**
* 聲明此方法用來處理調用對象中木多(zhōng)不存在的方法
*/
function __學物call($funName, $argu錯朋ments)
{
ech日舞o "你(nǐ)所調用的函數:&quo吃秒t; . $funName . "(年門參數:" ; //風計 輸出調用不存在的方法名
&nb鐘媽sp; print_r($arguments);在路 // 輸出調用不存在的方法時的參數列表
echo些議 ")不存在!
\n"; // 結束換行 &nbs歌站p; 會我
} 唱務 &n海路bsp; &nbs們畫p; &nb從他sp; &nbs資員p;
}
$Person = new Person()機分; 刀行
$Person->run("teacher"土睡;); // 調用對象中(zhōng)不存在的方法,則自動(dòng)要頻調用了對象中(zhōng)的__call()方法光通
$Person->eat("不河;小明", "蘋果&qu少土ot;); 鐘亮
$Person->say(); &紙的nbsp; 道樹 &n上關bsp;
運行結果:
你(nǐ)所調用的函數:run(參數:Arr唱購ay ( [0] => teacher ) 年呢)不存在!
你(nǐ)所調用的函數:eat(參數:Array ( 生玩[0] => 小明 [1] => 蘋果 ) )煙鐘不存在!
Hello, world!
四、 __callStatic(),用靜态方式中(zh錢她ōng)調用一個(gè)不可(kě)訪問(wèn)方法時調用
此方法與上面所說的 __call() 功能除了 __callSta公通tic() 是未靜态方法準備的之外,其它都男道是一樣的。
請看下(xià)面代碼:
<?php
class Person
{
functio內還n say()
{
不房 echo "Hello, world!
";
}
/**
* 聲裡些明此方法用來處理調用對象中(zhōng)不存在的方法
*/
public stat兒報ic function __callStatic($funName, $雜大arguments)
{
echo &quo道聽t;你(nǐ)所調用的靜态方法:" . $fu可店nName . "(參數:" ; //吃農 輸出調用不存在的方法名
森些 print_r($arguments); 知山// 輸出調用不存在的方法時的參數列表
照船 echo ")不存在!
\n"; // 結束換行
}
}
$Person = new Person愛書();
$Person::run("teacher&qu有筆ot;); // 調用對象中(zhōng)不存在的方法,則自動朋新(dòng)調用了對象中(zhōng)的_音技_call()方法
$Person::eat("小明"城北;, "蘋果");
$Person->say();
運行結果如(rú)下(xià):
你(nǐ)所調用的靜态方法:run(參數:Ar男件ray ( [0] => teacher ) )不存在!
你(nǐ)所調用的靜态方法:eat(參數:Array ( [0] =&了小gt; 小明 [1] => 蘋果 ) )不存在!
Hello, world!
五、 __get(),獲得一個(gè)類的成員變量時調門光用
在 php 面向對象編程中(zhōng),類的成員屬性被設定為 private如可 後,如(rú)果我們試圖在外面調用它則會出現“不能訪問(w些拍èn)某個(gè)私有屬性”的錯誤。那麼為了解決這個(我拍gè)問(wèn)題,我們可(kě)以使用魔術(shù)方法 __get()。作時
魔術(shù)方法__get()的作用
在程序運行過程中(zhōng),通(tōng)過它可(kě)以在對象些在的外部獲取私有成員屬性的值。
我們通(tōng)過下(xià)面的 __get() 的實例來更進一步的連接它票視吧:
<?php
class Person
{
private $name;
private $age;
function __construct($na但外me="", $age=1)
{
$this水花->name = $name;
會去 $this->age = $age;
}
/**
* 湖嗎在類中(zhōng)添加__get()方法,在直接獲取屬性值時自動拍懂(dòng)調用一次,以屬性名作為參數傳入并處理
看湖* @param $propertyName
*人跳
* @return int
*/
public func爸市tion __get($propertyName)
{ 筆紅
if ($prop視制ertyName == "age&qu子行ot;) {
學校 if ($this->age > 30) {
日北 &nbs雜北p; return $this->道姐age - 10;
&nbs冷錯p; } else {
&議去nbsp; return $請黃this->$propertyName;
&愛金nbsp; }
姐都} else {
&nb自為sp; return $this->$p頻鐵ropertyName;
}
}
}
$Person = new Person("們亮小明", 60);  湖問;// 通(tōng)過Person類實例化的對象,并通(tōng)過音公構造方法為屬性賦初值
echo "姓名:"不土 . $Person->name . "
"; // 直接訪問(w志動èn)私有屬性name,自動(dòng)調用了__get水身()方法可(kě)以間接獲取
echo "年齡:" . $Pe謝知rson->age . "
"; // 自動(dòng)調用了__ge什話t()方法,根據對象本身的情況會返回不同的值
運行結果:
姓名:小明
年齡:50
六、 __set(),設置一個(gè)類的成員變量時調用
__set() 的作用:
__set( $property, $v新生alue )` 方法用來設置私有屬性, 給一個(gè)未定義的屬性賦值時土山,此方法會被觸發,傳遞的參數是被設置的屬性名和(hé)值。
請看下(xià)面的演示代碼:
<?php
class Person
{
private $na和門me;
private $age;頻志
public function _線我_construct($name=&quo樹秒t;", $age=25)
{
$this->長金;name = $name;
$this-&g房醫t;age = $age;
}
/**
* 聲明魔術(shù)方法子醫需要兩個(gè)參數,真接為私有屬性賦值時自動(dòng)調用,并可(kě)讀身以屏蔽一些非法賦值
* @param $我醫property
* @param $value
*/
public 黃書function __set($property, $value科通) {
if ($pro東從perty=="age")
{
&靜務nbsp; if ($value > 150 || $報也value < 0) {
&長很nbsp; return;
&nb街師sp; }
}
$this-&g微公t;$property = $value;
}
/**
* 在類中(zhōng城農)聲明說話的方法,将所有的私有屬性說出
*/
public function湖能 say(){
&樂熱nbsp; echo "我叫".$河線this->name.",今年".$th外吧is->age."歲了"資問;
}
}
$Person=new Person("小明", 25);我熱 //注意,初始值将被下(xià)面所改變
//自動(dòng)調用了__set()老也函數,将屬性名name傳給第一個(gè)參男紅數,将屬性值”李四”傳給第二個(gè)參數體森
$Person->name = "小紅";&劇民nbsp; //賦藍錯值成功。如(rú)果沒有__set(),則出錯。
//自動(dòng)調用了__set()函數,将屬性我暗名age傳給第一個(gè)參數,将屬性值26如要傳給第二個(gè)參數
$Person->age = 16; //賦值成功
$Person->age = 160; /做那/160是一個(gè)非法值,賦值失效
$Person->say(); //輸出:我叫小資線紅,今年16歲了
運行結果:
我叫小紅,今年16歲了
七、 __isset(),當對不可(kě)訪問(wèn)現草屬性調用isset()或empty()時調用
在看這個(gè)方法之前我們看一下(xià)isset()函數的應用,iss金件et()是測定變量是否設定用的函數,傳入一個(gè)變量作為參數,如(rú)為腦果傳入的變量存在則傳回true,否則傳回false。
那麼如(rú)果在一個(gè)對象外面使用isset()這個(gè)函從姐數去測定對象裡面的成員是否被設定可(kě)不可(kě)以北用用它呢(ne)?
分兩種情況,如(rú)果對象裡面成員是公有的,我們鐵草就可(kě)以使用這個(gè)函數來測定成員屬性,如(rú)果是私有的成員來事屬性,這個(gè)函數就不起作用了,原因就是因為私有的被封裝了,在外部不可南物(kě)見。那麼我們就不可(kě)以在對象的外部使用isset()函數來近什測定私有成員屬性是否被設定了呢(ne)?當然是可(kě)以的,市女但不是一成不變。你(nǐ)隻要在類裡面加上一個(gè)__isset雪黃()方法就可(kě)以了,當在類外部使用isset()服司函數來測定對象裡面的私有成員是否被設定時,就會自動(年男dòng)調用類裡面的__isset()方法了幫我們完成這樣的操作。
__isset()的作用:當對不可(kě)訪問(wèn)屬性請農調用 isset() 或 empty() 短歌時,__isset() 會被調用。
請看下(xià)面代碼演示:
<?php
class Person
{
public $sex;
private $name;
private $age;
public function __件頻construct($name=""飛外, $age=25, $sex='男(nán)'大做;)
{
$黑科this->name = $name;
答房$this->age = $age;
$this->s遠窗ex = $sex;
}
/**
*兵農 @param $content
*
* @return boo是看l
*/
public f的窗unction __isset($content) {
&nb做來sp; echo "當在類外部使用isset(煙大)函數測定私有成員{$content}時,自動(dòn這照g)調用
";
&場船nbsp; echo isset($this-&妹間gt;$content);
}
}
$person = new Person("小明"他請, 25); // 初始賦值
echo isset($person->sex),"看房;
";
echo isset($person->name),"
";
echo isset($person->age),&q吧信uot;
";
運行結果如(rú)下(xià):
1 // public 可(kě)以 isset()
當在類外部使用isset()函數測定私有成員na拿中me時,自動(dòng)調用 // __但東isset() 内 第一個(gè)ech我很o
1 // __isset() 内第二個(g輛雜è)echo
當在類外部使用isset()函數測定私有成員age時,自動(dòng)調到道用 // __isset() 内 第一個(gè)echo
1 // __isset() 内第二個(gè)echo
八、 __unset(),當對不可(kě)訪問(wèn)屬性調用uns關慢et()時被調用。
看這個(gè)方法之前呢(ne),我們也先來看一下(xià日小) unset() 函數,unset()這個(gè)函數們用的作用是删除指定的變量且傳回true,參數為要删除的變量。
那麼如(rú)果在一個(gè)對象外部去删除對象内部的成員屬性用u綠制nset()函數可(kě)以嗎?
這裡自然也是分兩種情況:
1、 如(rú)果一個(gè)對象裡面的成員屬性是公有的,就暗海可(kě)以使用這個(gè)函數在對象外面删除對象的公有理關屬性。
2、 如(rú)果對象的成員屬性是私有的,我使用這個(gè)函數就沒有權限如哥去删除。
雖然有以上兩種情況,但我想說的是同樣如(rú)果你(nǐ)在一個(gè司火)對象裡面加上__unset()這個(gè鐵術)方法,就可(kě)以在對象的外部去删除對象的私有成員屬會黑性了。在對象裡面加上了__unset()這個(gè)方法之後,在對象熱綠外部使用“unset()”函數删除對象内部的私有成員屬性時,對話頻象會自動(dòng)調用__unset()函數來幫我們删除對議廠象内部的私有成員屬性。
請看如(rú)下(xià)代碼:
<?php
class Person
{
public $sex;但一
private $name;
privat子事e $age;
public function __c黃說onstruct($name="",又房 $age=25, $sex南樹='男(nán)')
{
說銀$this->name = $name;
&n黃議bsp; $this->age 聽吃 = $age;
&nbs麗弟p; $this->sex = $sex少些;
}
/**
* @param $con什長tent
*
* @re聽術turn bool
*/能如
public functio新能n __unset($content) {
&n女報bsp; echo "當在類外部使用unset()函數來删除私低公有成員時自動(dòng)調用的
";
頻海 echo isset($this看票->$content);
}
}
$person = new Person("小明&quo見長t;, 25); // 初始賦值
unset($person->sex);
unset($person->name);
unset($person->age);
運行結果:
當在類外部使用unset()函數來删除私有成員時自動(dòng)調用的路新
1當在類外部使用unset()函數來删除私有成員時自動(d為懂òng)調用的
1
九、 __sleep(),執行serialize()時,先會調用這個(gè)函笑黑數
serialize() 函數會檢查類中(路到zhōng)是否存在一個(gè)魔術(shù)方法 事花__sleep()。如(rú)果存在,則該方法會優先被調妹黑用,然後才執行序列化操作。
此功能可(kě)以用于清理對象,并返回一個(gè)微醫包含對象中(zhōng)所有應被序列化的變量名稱的數組。
如(rú)果該方法未返回任何内容,則 NULL 被序列化,并産生一個秒如(gè) E_NOTICE 級别的錯誤。
注意:
__sleep() 不能返回父類的私有成員的名字。這樣做會産生一個(gè)雨商 E_NOTICE 級别的錯誤。可(kě)西到以用 Serializable 接口來替代。
作用:
__sleep() 方法常用于提交未提交的數據,或類似的清理操師要作。同時,如(rú)果有一些很大的對象,但不需要全部保存,這個(g問有è)功能就很好用。
具體請參考如(rú)下(xià)代碼:
<?php
class Person
{
public $sex;
public $name;
public $a事計ge;
public func錯樹tion __construct($name=&quo也低t;", $age=25, $sex='男(ná黃山n)')
{
$thi你見s->name = $name;
&草房nbsp; $this->age&nbs了著p; = $age;
&n兵熱bsp; $this->sex = $sex和靜;
}
/**
* @return arra畫坐y
*/
public function __sleep(森票) {
&n不懂bsp; echo "當在類外部使用s員懂erialize()時會調用這裡的__sleep()方法
";
個花 $this->name = base64_en校雨code($this->name)跳還;
return arr冷醫ay('name', 'age數玩'); // 這裡必須返回一個(gè)數數村值,裡邊的元素表示返回的屬性名稱
}
}
$person = new Person(亮身9;小明'); // 初始賦值
echo serialize($person);
echo '
';
代碼運行結果:
當在類外部使用serialize()時會調用這裡的__sleep()方法
O:6:"Person":2:{s:4:&的就quot;name";s:8:"了人;5bCP5piO";s:3:"綠可;age";i:25;}
十、 __wakeup(),執行unserialize()時,先習慢會調用這個(gè)函數
如(rú)果說 __sleep() 是白的,那麼 __wakeup() 就市高是黑的了。
那麼為什麼呢(ne)?
因為:
與之相反,`unserialize()` 會檢查是否存在一個(gè) 城習`__wakeup()` 方法。如(rú)果存在,則會窗裡先調用 `__wakeup` 方法,預先準備對暗慢象需要的資(zī)源。
作用:
__wakeup() 經常用在反序列化操作中房那(zhōng),例如(rú)重新建立數據庫連接,或執行話木其它初始化操作。
還是看代碼:
<?php
class Person
{
public $sex;能員
public $na家友me;
public $age;舊你
public function _船影_construct($name="",&n姐為bsp; $age=25, $sex='男(n自問án)')
{
$this->照拿name = $name;
照煙 $this->age = $age;
$this-的很>sex = $sex;筆劇
}
/**
* @return arra到紙y
*/
public年了 function __sleep() {
購著 echo "當在類外部使用seria化河lize()時會調用這裡的__sleep()方法
";
$this-&時人gt;name = base64_encode($this-&風就gt;name);
拍答 return array('name', &多弟#39;age'); // 這裡必須爸刀返回一個(gè)數值,裡邊的元素表示返回的屬性名稱
}
/**
* __放歌wakeup
*/
public function __wakeup民匠() {
&空作nbsp; echo "當在類外部銀日使用unserialize()時會調用這裡的_玩書_wakeup()方法
";
&nbs愛有p; $this->name = 2;
&低海nbsp; $this->sex 務工= '男(nán)';
&nbs在看p; // 這裡不需要返回數組
}
}
$person = new Person('小明費計'); // 初始賦值
var_dump(serialize($person));
var_dump(unserialize(serialize($per微短son)));
運行結果:
當在類外部使用serialize()時會調用這裡的__sleep()年場方法
string(58) "O:6:"Pers跳花on":2:{s:4:"name";s:8:鄉化"5bCP5piO"高紅;s:3:"age";i:男請25;}" 當在類外部使用serialize()時唱書會調用這裡的__sleep()方法
當在類外部使用unserialize()時會調用這裡的__w紅裡akeup()方法
object(Person)#2 (3) { ["sex&qu美做ot;]=> string(3) "男(nán)鐵務" ["name"]=> int(2吃現) ["age"]=> int志輛(25) }
十一、 __toString(),類被當成來北字符串時的回應方法
作用:
__toString() 方法用于一個(gè)銀北類被當成字符串時應怎樣回應。例如(rú) `echo $obj;月門` 應該顯示些什麼。
注意:
此方法必須返回一個(gè)字符串,否則将發出一條 司拿`E_RECOVERABLE_ERROR` 級别的緻命錯誤。
警告:
不能在 __toString() 方法中(zhōng)抛出異常。這麼做會導緻緻道喝命錯誤。
代碼:
<?php
class Person
{
public $sex;
public $name;
public 離體$age;
public function __constr業朋uct($name="",&nb生裡sp; $age=25, $sex='男(nán)')慢拍
{
&n票呢bsp; $this->name = $name;
$this-吧妹>age = $age;
&nbs木這p; $this->sex = $sex;
}
public fu離技nction __toString()
{
&nb問到sp; return '歌日;go go go';
}
}
$person = new Person('小明'); // 音商初始賦值
echo $person;
結果:
go go go
那麼如(rú)果類中(zhōng)沒有 __toString() 這離費個(gè)魔術(shù)方法運行會發生什麼呢(ne房吧)?讓我們來測試下(xià):
代碼:
<?php
class Person
{
public $sex藍聽;
public $name;
public $age;綠司
public fun樹有ction __construct($name="&qu站不ot;, $age=25, $sex=&新路#39;男(nán)')
{
 來物; $this->name = $票愛name;
身物 $this->age = $age;
&nbs和愛p; $this->sex = $快費sex;
}
}
$person = new Person('小明'一務;); // 初始賦值
echo $person;
結果:
Catchable fatal error: Object of c討那lass Person could not be converted t高數o string in D:\phpStudy\WWW\t年農est\index.php on lin裡短e 18
很明顯,頁面報了一個(gè)緻命錯誤,這是語法所不允許的。
十二、 __invoke(),調用函數的方式調用一雪月個(gè)對象時的回應方法
作用:
當嘗試以調用函數的方式調用一個(gè)對象時,__in街很voke() 方法會被自動(dòng)調用。
注意:
本特性隻在 PHP 5.3.0 及以上版本有效。
直接上代碼:
<?php
class Person
{
public $sex;
public $name;
public $age;
public function __cons站議truct($name="", $a得區ge=25, $sex='男(nán村外)')
{
$th務計is->name = $name;
$thi歌年s->age = $ag車又e;
&nbs作車p; $this->sex = $sex;
}
public function農會 __invoke() {
echo '這制黑可(kě)是一個(gè)對象哦'火機;
}
}
$person = new Person(雪員39;小明'); // 初始賦值
$person();
查看運行結果:
這可(kě)是一個(gè)對象哦
當然,如(rú)果你(nǐ)執意要将對象當函數方法使用,那麼會得到下(xià)但文面結果:
Fatal error: Function na熱著me must be a string in D:\phpStudy冷分\WWW\test\index.php on國村 line 18
十三、 __set_state(),調用var_export()導農離出類時,此靜态方法會被調用。
作用:
自 PHP 5.1.0 起,當調用 var_export()明家 導出類時,此靜态方法會被自動(dòng)調用。
參數:
本方法的唯一參數是一個(gè)數組,其中(zh新上ōng)包含按 array('property' =&吃厭gt; value, ...) 格式排列的類學煙屬性。
下(xià)面我們先來看看在沒有加 __set路小_state() 情況按下(xià),代碼及運行結果如(rú)何:
上代碼:
<?php
class Person
{
public $sex;
public $name;
public $age;
public function __cons時商truct($name="", 話們; $age=25, $sex='男(nán)唱問')
{
&水哥nbsp; $this->name 資討= $name;
見場$this->age = $age;
&nb遠友sp; $this->sex =電我 $sex;
}
}
$person = new Person('電時;小明'); // 初始賦值
var_export($person);
看結果:
Person::__set_state(arra物就y( 'sex' => '男(nán)&下大#39;, 'name' => '小明'得森;, 'age' => 25, ))
很明顯,将對象中(zhōng)的屬性都打印出來了
加了 __set_state() 之後:
繼續上代碼:
<?php
class Person
{
public $se科西x;
public $name去朋;
public $劇話age;
public通兵 function __construct($name=舞鐘"", $離高age=25, $sex='男(nán)')
{
$this水相->name = $name;
唱歌 $this->age = $age;
$this->術問;sex = $sex;
}
public s火火tatic function __set_state($an_array歌白)
{
&nb靜讀sp; $a = new Person();大那
&nb妹可sp; $a->name = $an_array['相數;name'];
re服又turn $a;
}
}
$person = new Person('電對小明'); // 初始賦值
$person->name = '小紅';
var_export($person);
繼續看結果:
Person::__set_state(array綠樹( 'sex' => 歌費9;男(nán)', 'name一那' => '小紅', 'ag市樂e' => 25, ))
十四、 __clone(),當對象複制完成時調用
在多數情況下(xià),我們并不需要完全複制一個(gè)對象來舞文獲得其中(zhōng)屬性。但有一個(gè)情況下(xià)确實需要知睡:如(rú)果你(nǐ)有一個(gè) GTK 窗口對象,該對象持有窗口相來道關(guān)的資(zī)源。你(nǐ)可(kě)能會想複制一雨很個(gè)新的窗口,保持所有屬性與原來的窗口相同,市紅但必須是一個(gè)新的對象(因為如(rú)果不是新的湖知對象,那麼一個(gè)窗口中(zhōng)的改變就會影響到計小另一個(gè)窗口)。還有一種情況:如(rú)果對象 A 中(zh些是ōng)保存着對象 B 的引用,當你(nǐ)複制對象 A 時,你(nǐ)商音想其中(zhōng)使用的對象不再是對象 B 而是 B 的一個(gè)制影副本,那麼你(nǐ)必須得到對象 A 的一個(gè)副本。
作用:
對象複制可(kě)以通(tōng)過 clone 關(guān問還)鍵字來完成(如(rú)果可(kě)能,這将調用對象的 __cl冷謝one() 方法)。對象中(zhōng)的 __clone() 方法她師不能被直接調用。
語法:
$copy_of_object = clone $object;
注意:
當對象被複制後,PHP 5 會對對象的所有嗎都屬性執行一個(gè)淺複制(shallow copy)。音兵所有的引用屬性 仍然會是一個(gè)指向原來的變量的雨哥引用。
當複制完成時,如(rú)果定義了 __clone() 方法,則新創建的對象知答(複制生成的對象)中(zhōng)的 __clone() 方法會被調用,可(街校kě)用于修改屬性的值(如(rú)果有必要的麗公話)。
看代碼:
<?php
class Person
{
public $個慢sex;
public $n說民ame;
public $age;
public fu海動nction __construct($name=術錯"", $a錢資ge=25, $sex='男(nán)')
{
$this->裡間;name = $name;
有為 $this->age&n地地bsp; = $age;
$this->們我sex = $sex;
}
public functio做大n __clone()
{
echo __ME來黑THOD__."你(nǐ)正在克隆對風村象
";
}
}
$person = new Person('小明'); // 事子初始賦值
$person2 = clone $person;
var_dump('persion1外下:');
var_dump($person);
echo '
';
var_dump('persion2:');
var_dump($person2);
看結果:
Person::__clone你(nǐ)正在克隆對象中資
string(9) "persion1:"湖錢 object(Person)#1 (3) 說文{ ["sex"]=北車> string(3) "聽些男(nán)" ["name"內為;]=> string(6) "小明&qu我亮ot; ["age"]=> in民個t(25) }
string(9) "persion工兒2:" object(Person)#2 (3市黑) { ["sex"海樹]=> string(3) "男(nán)地和" ["name&qu大愛ot;]=> string(6) "小明" [制關"age"]=> int(25) }
克隆成功。
十五、__autoload(),嘗試加載未定義信城的類
作用:
你(nǐ)可(kě)以通(tōng)過定義這個(gè)函數來啟用類的自動(d的友òng)加載。
在魔術(shù)函數 __autoload() 方對門法出現以前,如(rú)果你(nǐ)要在一個(gè術輛)程序文(wén)件中(zhōng)實例化100個(gè)對象,跳大那麼你(nǐ)必須用include或者require包含進來100個(gè玩城)類文(wén)件,或者你(nǐ)把這100個國費(gè)類定義在同一個(gè)類文(wén)件中(z海山hōng) —— 相信這個(gè)文(wén)件一定會年日非常大,然後你(nǐ)就痛苦了。
但是有了 __autoload() 方法,以後就不必為此大傷腦筋了,工物這個(gè)類會在你(nǐ)實例化對象之前吧讀自動(dòng)加載制定的文(wén)件。
還是通(tōng)過例子(zǐ)來看看吧:
先看看以往的方式:
/**
* 文(wén)件non_autoload.php
*/
require_once('project/class/市拿A.php');
require_once('project/是綠class/B.php');&nbs弟年p;
require_once('project/class/C.php熱議39;);
if (條件A) {
$a = new A();&nb近樹sp;
$b = new喝作 B();
$c = new C();&nbs分市p;
// … 業(yè)務邏輯&熱作nbsp;
} else if (條件B) {
$a = newA場問();
$b = n用店ew B();
// … 業(yè)務邏輯 &nbs說科p;
}
看到了嗎?不用100個(gè),隻是3個(gè)看起來就有點煩了。而是子且這樣就會有一個(gè)問(wèn)題:如(rú)果腳本執行“條件B”這個(水聽gè)分支時,C.php這個(gè)文(wén)件其實沒有必要包含說慢。因為,任何一個(gè)被包含的文(wén)件,無論是否使用,均男年會被php引擎編譯。如(rú)果不使用,卻被編譯,這樣可(kě)以被視媽些作一種資(zī)源浪費。更進一步,如(rú錢知)果C.php包含了D.php,D.php包含了E.php。并且服湖大部分情況都執行“條件B”分支,那麼就會浪費一部分資(zī)源去編譯C.php舊麗,D.php,E.php三個(gè)“無用”的文(wén)件。
那麼如(rú)果使用 __autoload() 方式呢(ne美內)?
/**
* 文(wén)件autoload_demo商校.php
*/
function __aut紙木oload($className) {&n很木bsp;
$filePath = “proje樹光ct/class/{$className}.p習裡hp”;
if (is_reada請外ble($filePath)) {&nb聽動sp;
requir女月e($filePath);
}
}
if (條件A) {
$a = new 雨玩A();
$b = new B();&信子nbsp;
$c = new C(); 的體
// … 業(yè)務邏算她輯
} else if (條件B) {
$a = newA();草服
$b = new B(); &nb煙身sp;
// … 業(y樹討è)務邏輯
}
ok,不論效率怎麼用,最起碼界面看起來舒服多了,沒北討有太多冗餘的代。
再來看看這裡的效率如(rú)何,我們分析下(xià):也見
當php引擎第一次使用類A,但是找不到時,會自動(dòng)調用 __aut朋音oload 方法,并将類名“A”作為參數傳入。所以,我們在司拿 __autoload() 中(zhōng)需要的做醫吧的就是根據類名,找到相應的文(wén)件,并包含進來,如(r朋日ú)果我們的方法也找不到,那麼php引擎就會報錯了。
注意:
這裡可(kě)以隻用require,因為一旦包含進來後,ph高如p引擎再遇到類A時,将不會調用__autoload,而是直接使用内存中(zhō能中ng)的類A,不會導緻多次包含。
擴展:
其實php發展到今天,已經有将 `spl_autoload_re用低gister` — 注冊給定的函數作為 __autolo秒計ad 的實現了,但是這個(gè)不在啊本文(wén)講解之内,有興趣可(kě暗船)以自行看手冊。
十六、__debugInfo(),打印所需調試醫河信息
注意:
該方法在PHP 5.6.0及其以上版本才可(kě)以話說用,如(rú)果你(nǐ)發現使用無效或者報錯,請查看啊你(nǐ)的版本我窗。
看代碼:
<?php
class C {
private $prop;
public function __con信到struct($val) {
$this->友唱;prop = $val;
}
/**
* @return ar地白ray
*/
public function __debugIn冷男fo() {
re計金turn [
&我要nbsp; 內錢9;propSquared' => $this->prop習白 ** 2,
];答很
}
}
var_dump(new C(42));
結果:
object(C)#1 (1) { [&quo雪志t;propSquared"]=> int(1764) 技放}
再次注意:
這裡的 `**` 是乘方的意思,也是在P吃著HP5.6.0及其以上才可(kě)以使用,詳情請查看P近熱HP手冊
總結
以上就是PHP中(zhōng)我了解到的魔術(s哥鄉hù)方法了,常用的包括 __set() __get() __aut窗內oload() 等應該熟悉,其他的了解也沒有飛哥關(guān)系,畢竟知識不怕多嘛。
好了,有興趣的或者我這裡沒有說明白的,可(kě)以參考農化啊官方文(wén)檔。