魔術方法__get()實例詳解
在PHP中以兩個下劃線開頭的方法,被稱爲"魔術方法"(Magic methods)。比如__construct(), __destruct (), __clone(),以及__call(),,__get(), __set(),__sleep(), __wakeup(), __toString(), __autoload()等,都是魔術方法。
如果希望PHP調用這些魔術方法,首先必須在類中定義,否則PHP不會執行未創建的魔術方法。
注意:
魔術方法是php中設置好的,所以不能自己去創建,只能用php中本來就存在的,否則會報錯。
__get()的作用爲:
__get():讀取不可訪問屬性的值(private,protected,不存在)時,php就會執行__get()方法。
我們來看個有關__get()的實例:
<?php class Person{ public $name; protected $age; function __construct($name,$age){ $this->name = $name; $this->age = $age; } function me(){ echo $this->name.' '.$this->age; } //魔術方法 function __get($pro){ if(isset($this->$pro)){ return $this->$pro; }else{ echo '屬性值:'.$pro.'不存在'; } } } $person = new Person('cyy',25); $person->me(); echo '<br>'; echo $person->age;
魔術方法__set()實例詳解
__set()的作用:
__set():在給不可訪問屬性賦值(private,protected,不存在)時,php就會執行__set()方法。
<?php class Person{ public $name; protected $age; function __construct($name,$age){ $this->name = $name; $this->age = $age; } function me(){ echo $this->name.' '.$this->age; } //魔術方法 function __get($pro){ if(isset($this->$pro)){ return $this->$pro; }else{ echo '屬性值:'.$pro.'不存在'; } } function __set($pro,$val){ if(isset($this->$pro)){ return $this->$pro = $val; }else{ echo '屬性值不存在'; } } } $person = new Person('cyy',25); $person->me(); echo '<br>'; $person->age = '66'; echo $person->age;
因爲$age是保護的,所以不允許訪問。那麼,我們就要藉助__set()魔術方法來實現。__set()方法包含兩個參數,分別表示變量名稱和變量值,兩個參數不可省略。
魔術方法___toString()實例詳解
__toString()方法會先將對象傳化成字符串在輸出,這樣就可以用echo或者print輸出了。
實例分析:
<?php class Person{ public $name; protected $age; function __construct($name,$age){ $this->name = $name; $this->age = $age; } //魔術方法 function __get($pro){ if(isset($this->$pro)){ return $this->$pro; }else{ echo '屬性值:'.$pro.'不存在'; } } function __set($pro,$val){ if(isset($this->$pro)){ return $this->$pro = $val; }else{ echo '屬性值不存在'; } } function __toString(){ return $this->name.' '.$this->age; } } $person = new Person('cyy',25); echo $person;
結果如下:
cyy 25
如果實例化一個類,然後直接echo這個類名,頁面上會顯示報錯信息: Object of class xx could not be converted to string。意思是對象的類不能轉換爲字符串輸出。所以我們加上__toString()方法,就可以了,在方法中直接返回需要的結果就可以了。
魔術方法__call()實例詳解
什麼是__call()魔術方法?
__call是魔術方法中的一個,當程序調用到當前類中未聲明或沒權限調用的方法時,就會調用__call方法。__call()方法包含兩個參數,即方法名和方法參數。其中,方法參數是以數組形式存在的。
<?php class Person{ public $name; protected $age; function __construct($name,$age){ $this->name = $name; $this->age = $age; } function __call($name,$arg){ echo '當方法不存在時我會被調用<br>'; echo '方法名:'.$name.', 參數爲:'; var_dump($arg); } } $person = new Person('cyy',25); $person->hh('a','b');
結果如下:
魔術方法__autoload()實例詳解
在寫代碼的時候,經常會遇到一個頭疼的問題,就是要在一個頁面中引入很多的類,需要用到include_once或者require_once()函數一個一個引入。當引入的內容不多時,還可以接受,但是如果有十幾個或者幾十個文件需要引入,操作次數多,煩躁不說,還會出現重複引入或者忘了引用的情況。
__autoload()方法可以自動實例化需要使用的類。當程序要用到一個類,但該類還沒有實例化時,PHP5將調用__autoload()方法,在指定的路徑下自動查找和該類名稱相同的文件。如果找到,程序則繼續執行;否則,報告錯誤。
注意:
其他所有的方法都是要在類的內部添加才起作用,__autoload()是唯一一個不在類中添加的方法
只要在頁面中使用到一個類,類名就會自動傳給這個參數。
舉個例子:
創建類文件person.class.php的代碼:
<?php class Person{ private $name; public function __construct($name){ $this->name = $name; } public function __toString(){ return $this->name; } }
在index.php文件下的代碼:
<?php function __autoload($class){ $classpath = $class.'.class.php'; if(file_exists($classpath)){ include_once($classpath); }else{ echo '類文件不存在'; } } $person = new Person('cyy'); echo $person;
結果如下:
報錯是由於php版本過高,PHP 7.2開始不主張使用function __autoload(){}來自動加載類文件。
可以換低版本php,或者使用推薦的 spl_autoload_register 方法
---來自陳鶯鶯呀的分享
php面向對象高級應用詳解(2)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.