這篇文章主要介紹了Yii框架元件和事件行為管理,詳細分析了Yii框架元件管理與行為管理的原理與使用技巧,需要的朋友可以參考下
本文實例講述了Yii框架元件和事件行為管理。分享給大家供大家參考,具體如下:
Yii是一個基於元件、用於開發大型 Web 應用的高效能 PHP 框架。 CComponent幾乎是所有類別的基類,它控制著元件與事件的管理,其方法與屬性如下,私有變數$_e資料存放事件(evnet,有些地方叫hook),$_m陣列存放行為(behavior)。
元件管理
YII是純oop框架,許多類別中的成員變數的受保護或是私有的,CComponent中利用php中的魔術方法__get(),__set()來存取和設定屬性,但這些方法的作用遠不如這些。下面用__get()來說明
public function __get($name) { $getter='get'.$name; if(method_exists($this,$getter)) return $this->$getter(); else if(strncasecmp($name,'on',2)===0 && method_exists($this,$name)) { // duplicating getEventHandlers() here for performance $name=strtolower($name); if(!isset($this->_e[$name])) $this->_e[$name]=new CList; return $this->_e[$name]; } else if(isset($this->_m[$name])) return $this->_m[$name]; else if(is_array($this->_m)) { foreach($this->_m as $object) { if($object->getEnabled() && (property_exists($object,$name) || $object->canGetProperty($name))) return $object->$name; } } throw new CException(Yii::t('yii','Property "{class}.{property}" is not defined.', array('{class}'=>get_class($this), '{property}'=>$name))); }
當CComponent或其子類別物件實例$obj->name的時候,__get($name)方法:
1、先判斷實例中是否有getName()方法,如果有則返回,如果沒有執行第2步
2、判斷是否是以on開頭的,以on開頭的一般都是CComponent子類別中預留的事件,用與掛在事件,透過method_exists($this,$name)判斷該name是否存在類別的實例中,如果存在,返回事件,否則執行第3步驟
3、如果name存在行為數組中,返回改行為,如果不存在,執行第4步
4、遍歷行為數組,數組中行為是CBehavior子類的實例,而CBehavior又是CComponent中子類,所以用遞歸的方法取得行為中的方法,如果沒有,執行第5步
5、拋出例外:請求的屬性不存在。
在CComponent子類別中可以重載__get()方法,如在CModule中加入了取得元件的判斷。這就注意一個問題了屬性和元件名最好不要重名,因為程式會優先載入元件,可能得到的不是我們想要的屬性,如果必須重名的話,就要用getter來取得屬性。
public function __get($name) { if($this->hasComponent($name)) return $this->getComponent($name); else return parent::__get($name); }
關於元件的載入與創建,上篇YII框架分析筆記1:YII執行流程中的第3點中有個問題:註冊框架核心組件的時候一下子載入這麼多,是不是影響效能呢?其實沒有,註冊的時候只是把組件和其對應的配置用鍵值對的形式保存在數組中(預先加載的除外),當用到時候才像上面那樣去創建組件,會通過YIIBase中的createComponent( )方法創建,並初始化。透過CModule或其子孫類別(如CWebApplication)呼叫__get()或getComponent()取得元件時,CModule透過$_components陣列建立物件池,確保每個元件在一次請求中只會實例化一次。
事件行為管理
事件相當於對一個元件的擴充或插件,以元件中預留的鉤子實作元件內部呼叫外部、外部對元件部分控制。在CComponent子類別中可以定義以on開頭的方法為事件,類似js中的onclick、onchange等,其實原理差不多。所有事件是與CComponent在同一文件中CEvent的子類別。
/** * Raised right BEFORE the application processes the request. * @param CEvent $event the event parameter */ public function onBeginRequest($event) { $this->raiseEvent('onBeginRequest',$event); } /** * Runs the application. * This method loads static application components. Derived classes usually overrides this * method to do more application-specific tasks. * Remember to call the parent implementation so that static application components are loaded. */ public function run() { if($this->hasEventHandler('onBeginRequest')) $this->onBeginRequest(new CEvent($this)); $this->processRequest(); if($this->hasEventHandler('onEndRequest')) $this->onEndRequest(new CEvent($this)); }
例如在CApplication中呼叫run()方法在處理請求之前先判斷外部是否傳人onBeginRequest事件的句柄,如果有則透過onBeginRequest($event )方法呼叫CComponent中的raiseEvent()方法執行句柄中的函數或方法。
行為是事件的升級版,所有的行為都是CBehavior的子類別。分析上面的__get()方法分析第4步驟可以看出來行為的作用是完全擴展元件的特性,可以是屬性、方法、事件甚至行為,這樣讓程式開發更有彈性。
行為的另一個作用是將相似事件句柄放在一起,在行為執行attach()方法的時候會將events()方法中傳回的事件句柄綁定,這樣做達到面向管理和擴展的目的。例如CModelBehavior中將model相關的事件集中起來,便於其子類別的複用,當我們需求為model添加行為的時候可以繼承它。
以上就是本文的全部內容,希望對大家的學習有所幫助,更多相關內容請關注PHP中文網!
相關推薦:
以上是對於Yii框架元件和事件行為管理的解析的詳細內容。更多資訊請關注PHP中文網其他相關文章!