首頁  >  文章  >  後端開發  >  php類別中的魔術方法及類別的自動加載

php類別中的魔術方法及類別的自動加載

WBOY
WBOY原創
2016-07-25 09:03:52923瀏覽
  1. class Connection {
  2. protected $link;
  3. private $server, $username, $password, $db;
  4. public function __password, $db;
  5. public function structstruction ($server, $username, $password, $db) {
  6. $this->server = $server;
  7. $this->username = $username;
  8. $this->password = $password;
  9. $this->db = $db;
  10. $this->connect();
  11. }
  12. private function connect() {
  13. $this->link = mysql_connect( $this->server, $this->username, $this->password);
  14. mysql_select_db($this->db, $this->link);
  15. }
  16. public function __sleep () {//系列化時只需保存這些屬性的值
  17. return array('server', 'username', 'password', 'db');//必須傳回一個陣列
  18. }
  19. public function __wakeup() { //反系列化得到物件後立即連接資料庫
  20. $this->connect();
  21. }
  22. }
複製代碼

__toString(): 試圖將物件作為字串使用時被調用,傳回字串,類似 js 物件的 toString()

__invoke(): 將一個物件作為函數呼叫時被呼叫。如 $object($a,$b) 將呼叫 $object->__invoke($a,$b)

__set_state() : 對一個物件使用 var_export() 時被調用,其返回值將被列印

__clone(): 對一個物件使用clone 操作時被調用,無返回值,該方法可用於在返回clone 得到的物件之前修改其屬性使得clone 得到的物件與被操作的物件屬性值可以不同,但​​並不能透過返回null 或false 來阻止物件複製操作, clone 操作得到的物件不是透過該方法的回傳值傳回的。

注意事項: __get、__set 方法可常用於彈性處理 物件私有屬性、保護屬性的存取。 由於 PHP 物件對於的方法使用 isset() 或 empty() 判定時,不會認為 方法是一個可訪問的屬性(寫多了 javascript 要注意了,PHP 裡面 屬性就是屬性方法就是方法不可混淆) 在使用__get 時,你可能會在該方法中對屬性使用isset($this->key) 判斷,尤其是要特別處理私有屬性的時候,這時要注意__set() 有沒有定義以及如何定義以免出現誤判。 如果一個物件的方法在呼叫時不需要傳參,或者傳參是固定的,可以透過 __get() 方法將方法屬性化,在 __get() 裡面自動呼叫該方法並將值傳回。

例如在類別內定義 __get 方法如下:

  1. public function __get($key){

  2. if(property_exists($this,$key)){
  3. return $this->$key; //私有、保護屬性允許存取
  4. }else if(method_exists($this,'get'.$key)){
  5. return $this->{'get'. $key}();
  6. //或....
  7. // $methodName = 'get'.$key;
  8. //return $this-> $methodName();
  9. } else{
  10. thrown new Exception('class '.__class__.' do not has property '.$key);
  11. }
  12. }
  13. //方法屬性化訪問:

  14. $obj->getModelName();
  15. $obj->ModelName; //屬性化
複製程式碼

unserialize() 方法:當試圖反序列化一個物件時,該函數需要知道物件的類,如果這個系列化字串從其他方式得來,腳本環境中沒有定義物件的類,就需要將類別的文件引入,unserialize() 第二個參數是可選的callback 型參數,用於引入類別所在的文件。 function importClass($calssName){ include('xxxx.php'); //包含該類別的文件 } unserialize($objstr,$callbackName);

類別的自動載入: __autoload()

__autoload() 是PHP執行環境中約定的函數而非某個類別的方法,如果一個類別在使用之前沒有載入到目前文件,會自動呼叫__autoload() 函數來載入該類,通常這些類別的載入規則都是約定的,例如這些類別包含在以類別名稱命名的檔案內,該方法可以實現類別的按需加載,避免在腳本執行前加載不必要的類別從而降低資源佔用、提交效能。

注意:__autoload() 內的錯誤不能被 try-catch 捕捉。

  1. function __autoload($class_name){
  2. require_once(PATH.'/calsses/'.$class_name.'.php');
  3. }
  4. $obj1 = new mycalss1();
複製程式碼

註冊 __autoload() 自動呼叫的函數: spl 程式碼庫在 PHP5.0 之後預設自動啟用 spl_autoload_register([callback]); //不將特定實作的載入程式碼寫在 __autoload() 內,可使用函數註冊回呼函數。

如果使用類別的方法作為回呼函數需要傳入一個陣列: spl_autoload_register(array('class_name'|$obj,'method_name'));

例如: spl_autoload_register(array($this,'autoloadClass')); spl_autoload_register(array('YiiBase','autoload'));// YII 框架的自動載入類別的實現, YiiBase 類別實作了一個autoload 方法。 spl_autoload_register() 可以註冊多個載入函數,成功載入類別檔案之前將逐一嘗試所有註冊的載入函數。這在不同的類別使用不同邏輯來匯入類別文件的時候很有用。 spl_autoload_unregister(); //取消某個註冊的載入函數,參數與 spl_autoload_register() 相同. spl_autoload_functions();// 以陣列形式傳回所有註冊的 __autoload() 函數

spl_autoload(class_name[,file_extentions]); // __autoload() 函數的預設實作。 spl_autoload_register() 被呼叫時如果沒有傳入函數名,則預設使用該函數,該函數的執行規則是: 類別名稱轉為小寫作為檔案名,傳入的file_extentions(多個副檔名以逗號隔開,預設為.inc 和.php)為副檔名,根據所得的檔名嘗試在php.ini 內設定的include paths 中搜尋。

spl_autoload_call(class_name);//手動呼叫所有已註冊的 __autoload() 函數來主動載入類別文件 spl_autoload_extentions([file_extentions]); //註冊或傳回 spl_autoload() 中可以使用的檔案副檔名,副檔名可以是 .a.b 這樣的形式,例如: spl_autoload_extentions(".class.php"); spl_autoload_register(); //使用spl_autoload() 來嘗試自動載入類別文件 //這樣 spl_autoload('myclassName'); 會嘗試載入 檔案 "myclassName.class.php" .



陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn