在 PHP 中以兩個下劃線開頭的方法,__construct(),__destruct (),__call(),__callStatic(),__get(),__set(),__isset(),__unset (),__sleep(),__wakeup() 等,被稱為"魔術方法"(Magic methods).
集合涵義
在PHP中以兩個下劃線開頭的方法,__construct(), __destruct (), __call(), __callStatic(),__get(), __set(), __isset(), __unset (), __sleep(), __wakeup(), __toString(), __set_state,() __clone() __autoload()等,被稱為"魔術方法"(Magic methods)。如果希望PHP調用這些魔術方法,首先必須的類中定義,否則PHP不會執行未創建的魔術方法。[1]
注意:PHP 將所有以 __(兩個下劃線)開頭的類方法保留為魔術方法,所以在定義類方法時,除了上述魔術方法,建議不要以 __ 為前綴.
魔術方法中文說明
PHP面向對象有哪些魔術方法,每個魔術方法如何如何,請寫個測試類并運行
_construct($argv1,$argv2,...)
功能:類的構造方法,作用就是初始化對象
參數:任意多個,任意類型
返回值:無
__destruct()
功能:類的析構方法,對象被銷毀時被調用的,作用是釋放內存
參數:無
返回值:無
__get($name)
功能:當程序試圖調用一個未定義或者不可見的成員變量的時候就會自動調用該方法,這個時候程序試圖調用*的成員變量的返回值是該方法的返回值;
參數:$name為試圖調用的成員變量的名稱,這個參數的傳遞是PHP自動完成的;
返回值:類型(不確定)注意該方法可以設置成私有的(構造方法不要設置成私有的)。
__set($name,$value)魔術方法
功能:當程序試圖給一個未定義或者不可見的成員變量賦值的時候就會自動調用該方法;
參數:$name,$value分別表示試圖賦值的成員變量名稱和成員變量的值,這兩個參數的傳遞是PHP自動完成的;
返回值:這個方法不會返回值 注意該方法可以設置成私有的(構造方法不要設置成私有的)。
__isset($name)
功能:當用isset($name)檢測一個私有的成員變量的時候就會自動調用該方法,這個時候isset($name)的返回值就為該方法的返回值經過轉化的布爾值(<除“0”>非空的字符串,非零,true,有單元的數組將會轉化為true;0,"0",空*字符串,NULL,沒有單元的數組將會轉化為false);
參數:$name為試圖檢測的成員變量的名稱,這個參數的傳遞是PHP自動完成的;
返回值:類型(不確定)注意該方法可以設置成私有的(構造方法不要設置成私有的),當用isset()函數檢測的是公有的成員變量的時候可以直接檢測,如果沒有__isset()方法而直接檢測私有成員會得到不準確的結果即isset()會始終返回false;
_unset($name)
功能:當用unset($name)撤銷一個私有的成員變量的時候就會自動調用該方法;
參數:$name為試圖撤銷的成員變量的名稱,這個參數的傳遞是PHP自動完成的;
返回值:不能返回值,強制返回值將會出錯,當用unset()函數撤銷的是公有的成員變量的時候可以直接撤銷,如果沒有__unset()方法而直接撤銷私有成員不會成功;
__toString()
功能:當程度試圖輸出一個對象類型的變量的時候PHP會自動調用該方法;
參數:沒有參數,如果有會提示出錯;
返回值:字符型(該方法必須通過return返回一個字符串);
__clone()
功能:在用clone關鍵字克隆一個對象的時候PHP會自動調用這個方法,是為了給克隆出來的對象增添自己的屬性和方法;
參數:不用傳遞參數;
返回值:不用返回值;
_call($name,$argument)
功能:當程序試圖調用一個不存在的成員方法的時候會自動調用該方法;
參數:PHP將自動將調用的不存在的方法名傳遞給$name,不存在的方法中的參數整合為一個數組傳遞給*$argument;
返回值:不用返回值;
_sleep()
功能:使用serialize()函數時,如果實例化的對象中包含__sleep()方法,則會先執行__sleep()方法,該方法可以清除對象并返回該對象中所有變量的數組。使用__sleep()方法的目的是關閉對象可能具有的數據庫連接等類似的善后工作
參數:無需要傳遞參數
返回值:數組類型(Array)該對象中所有變量的數組
__wakeup()
功能:使用unserialize()函數重新還原一個被serialize()函數序列化的對象,__wakeup()方法則是恢復序列化中可能丟失的數據庫連接及相關工作
參數:無需要傳遞參數
返回值:----------------------------
__set_state($arr)
功能:可以通過var_export()來訪問類的靜態方法__set_state(),該方法必須是靜態的且必須返回一個對象
參數:$arr為一個數組
返回值:為一個對象
__autoload($class_name)
功能:在指定的路徑下自動查找并導入實例化需要使用的類
參數:$class_name為類名
返回值:*__callStatic($name,$argument)
功能:當程序試圖在靜態方法中調用一個未定義或者不可見的成員方法的時候會自動調用該方法;
參數:PHP將自動將調用的不存在的方法名傳遞給$name,不存在的方法中的參數整合為一個數組傳遞給$argument;
返回值:不用返回值;
注意:PHP5.3以上的版本支持該魔術方法
注意:__classStatic()方法必須被申明為public并且為static,否則會產生一個warning錯誤.
__invoke($x,$y,...)
功能:當嘗試以調用函數的方式調用一個對象時,__invoke 方法會被自動調用。
參數:以函數調用方法調用一個對象時傳遞的任意多個參數
返回值:不確定*
注意:PHP5.3以上的版本支持該魔術方法
魔術方法例子,代碼如下:
- <?php
- class XuDianYang{
- public $sex;
- public $age;
- private $girlfriend='xx';
- public function __construct($sex,$age){
- $this->sex=$sex;
- $this->age=$age;
- }
- public function __get($name){
- echo __class__."::".$name."不存在或者不可見";
- }
- public function __set($name,$value){
- echo __class__."::".$name."由于不在在或者不可見,賦值失敗";
- }
- public function __isset($name){
- if(isset($this->$name)){
- echo 1;
- }else{
- echo 0;
- }
- }
- public function __unset($name){
- unset($this->$name);
- }
- public function __toString(){
- return __class__;
- }
- public function __clone(){
- $this->sex='女';
- }
- public function __call($name,$argument){
- echo "方法".__class__."::".$name."不存在";
- }
- public function __sleep(){
- echo "I'm sleeping";
- foreach($this as $key=>$value){
- $arr[]=$key;
- }
- return $arr;
- }
- public function __wakeup(){
- echo "I wake up";
- }
- public function __set_state($arr){
- $obj=new CheShi();
- $obj->var1=$arr['sex'];
- $obj->var2=$arr['age'];
- return $obj;
- }
- }
- function __autoload($name){
- $class_path="./";
- include_once($class_path.$name.".class.php");
- }
- $xudianyang=new XuDianYang("男",21);
- echo "<br/>";
- //正常訪問sex屬性
- echo $xudianyang->sex;
- echo "<br/>";
- //由于不存在weight屬性,將自動調用__get()方法
- echo $xudianyang->weight;
- echo "<br/>";
- //由于不可見(即私有),將自動調用__get()方法
- $xudianyang->girlfriend;
- echo "<br/>";
- //由于不存在,賦值失敗,自動調用__set()方法
- $xudianyang->shengao="172cm";
- echo "<br/>";
- //檢測sex屬性是否存在,由于sex公有直接檢測
- var_dump(isset($xudianyang->sex));
- echo "<br/>";
- //檢測girlfriend是否存在,由于girlfriend私有,所以自動調用__isset()方法
- isset($xudianyang->girlfriend);
- echo "<br/>"; //開源軟件:Vevb.com
- //撤消girlfriend,由于girlfriend私有,所以自動調用__unset()方法
- //unset($xudianyang->girlfriend);
- isset($xudianyang->girlfriend);
- echo "<br/>";
- //直接輸出一個對象,自動調用__toString()方法
- echo $xudianyang;
- echo "<br/>";
- $xu=clone $xudianyang;
- echo $xu->sex;
- echo "<br/>";
- //由于調用不存在的方法,自動調用__call()方法
- $xudianyang->walk();
- echo "<br/>";
- //序列化對象,自動調用__sleep()方法
- $a=serialize($xudianyang);
- echo "<br/>";
- echo "序列化的結果為:".$a;
- //反序列化對象,自動調用__wakeup()方法
- echo "<br/>";
- $b=unserialize($a);
- //反序列化的結果
- echo $b->sex;
- echo "<br/>";
- eval('$c='.var_export($xudianyang,true).";");
- echo $c->var1;
- ?>
- CheShi.class.php
- <?php
- class CheShi{
- public $var1;
- public $var2;
- }
- ?>
新聞熱點
疑難解答