1. 程式人生 > >巧用PHP中__get()魔術方法

巧用PHP中__get()魔術方法

獲取 function 變量 返回 lib 底層 lower php腳本 redis

PHP中的魔術方法有很多,這些魔術方法可以讓PHP腳本在某些特定的情況下自動調用。比如 __construct() 每次實例化一個類都會先調用該方法進行初始化。這裏我們講一下__get() 魔術方法的使用。讀取不可訪問屬性的值時,__get() 會被調用。也就是,當想要獲取一個類的私有屬性,或者獲取一個類並為定義的屬性時。該魔術方法會被調用。

下面有段代碼:

class Model
{

   //不存在的成員屬性自動調用
  function __get($name) 
  {
         //自動加載數據庫
        if(substr($name, 0,2) ==‘db‘){
            
$config = strtolower(substr($name, 2)); if(empty($this->objDb)){ $this->objDb = new LibDatabase($config); }else{ $this->objDb->config($config); } return $this->objDb; } // 自動加載redis if
(substr($name, 0,5) ==‘redis‘){ $config = strtolower(substr($name, 5)); if(empty($this->objRedis)){ $this->objRedis = new LibRedis($config); }else{ $this->objRedis->config($config); } return $this->objRedis; }
//自動加載excel插件 if(substr($name, 0,5) ==‘excel‘){ if(empty($this->objExcel)){ $this->objExcel = new LibExcel(); } return $this->objExcel; } throw new LinkException("變量{$name}不被支持,請預先Model中定義",EXCEPT_CORE); } } ?>

首先,該Model類有只有一個__get() 方法,沒有定義其他屬性,所有只要是訪問這個Model類的屬性,都會來調用這個__get() 方法。而傳入的參數$name就是想要調用Model類的屬性。

其次,__get() 方法裏有3個判斷,分別用於返回一個LibDatabase數據庫類和一個LibRedis緩存類和一個LibExcel 的Excel插件類的實例。

假設$mod 是Model的一個對象。我們來分析以下三中情況:

1、$mod->dbconfsys->getAll($sql);

2、$mod->redisconfsys->get($key);

3、$mod->excel->export($data);

第一個:訪問Model類的dbconfsys屬性。但是Model類中並沒有該屬性。所以 __get() 的第一個判讀成立,那麽會返回LibDatabase(‘confsys’)的實例。這裏confsys其實是一個數據庫的配置。如果有多個數據庫的配置比如confadmin、conftest等,都可以使用dbconfadmin和dbconftest來實例化該數據庫的一個連接對象。當然連接的處理以及數據處理是在LibDatabase裏實現的。最後調用該實例的getAll方法執行sql語句。

第二個:訪問Model類的redisconfsys屬性,同理,此時 __get() 的第二個判斷成立。返回的是LibRedis(‘confsys’)的實例。這裏的confsys則是一個redis的配置。像數據庫實例一樣,如果有多個配置,也是同樣的處理方式。最後調用該實例的get方法獲取某個鍵的值。

第三個:訪問Model類的excel 屬性,此時__get() 的第三個判斷成立。返回的是LibExcel()的實例。最後調用export方法導出數據。

這個Model類可以作為基礎的底層模型。然後系統中所有數據表的模型或者每個模塊功能的模型都繼承Model,同樣可以使用該Model的功能,這裏需要註意的是每種對象的調用都需要先早Model中做好判斷處理。

巧用PHP中__get()魔術方法