本文實例講述了Yii框架組件和事件行為管理。分享給大家供大家參考,具體如下:
Yii是一個基于組件、用于開發(fā)大型 Web 應用的高性能 PHP 框架。CComponent幾乎是所有類的基類,它控制著組件與事件的管理,其方法與屬性如下,私有變量$_e數(shù)據(jù)存放事件(evnet,有些地方叫hook),$_m數(shù)組存放行為(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()方法,如果有則返回 ,如果沒有執(zhí)行第2步
2、判斷是否是以on開頭的,以on開頭的一般都是CComponent子類中預留的事件,用與掛在事件,通過method_exists($this,$name)判斷該name是否存在類的實例中,如果存在,返回事件,否則執(zhí)行第3步
3、如果name存在行為數(shù)組中,返回改行為,如果不存在,執(zhí)行第4步
4、遍歷行為數(shù)組,數(shù)組中行為是CBehavior子類的實例,而CBehavior又是CComponent中子類,所以用遞歸的方法獲取行為中的方法,如果沒有,執(zhí)行第5步
5、拋出異常:請求的屬性不存在。
在CComponent子類中可以重載__get()方法,如在CModule中加入了獲取組件的判斷。這就注意一個問題了屬性和組件名最好不要重名,因為程序會優(yōu)先加載組件,可能得到的不是我們想要的屬性,如果必須重名的話,就要用getter獲取屬性。
public function __get($name) if($this- hasComponent($name)) return $this- getComponent($name); else return parent::__get($name);}
關于組件的加載與創(chuàng)建,上篇YII框架分析筆記1:YII執(zhí)行流程中的第3點中有個疑問:注冊框架核心組件的時候一下子加載這么多,是不是影響性能呢?其實沒有,注冊的時候只是把組件和其對應的配置用鍵值對的形式保存在數(shù)組中(預加載的除外),當用到時候才像上面那樣去創(chuàng)建組件,會通過YIIBase中的createComponent()方法創(chuàng)建,并初始化。通過CModule或其子孫類(如CWebApplication)調用__get()或getComponent()獲取組件時,CModule通過$_components數(shù)組建立對象池,確保每個組件在一次請求中只實例化一次。
事件行為管理
事件相當于對一個組件的擴展或者插件,以組件中預留的鉤子實現(xiàn)組件內部調用外部、外部對組件部分控制。在CComponent子類中可以定義以on開頭的方法為事件,類似于js中的onclick、onchange等,其實原理差不多。所有事件是與CComponent在同一文件中CEvent的子類。
/*** Raised right BEFORE the application processes the request.* @param CEvent $event the event parameterpublic 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()方法執(zhí)行句柄中的函數(shù)或者方法。
行為是事件的升級版,所有的行為都是CBehavior的子類。分析上面的__get()方法分析第4步可以看出來行為的作用是完全擴展組件的特性,可以是屬性、方法、事件甚至行為,這樣使程序開發(fā)更加靈活。
行為的另一個作用是將相似事件句柄放在一起,在行為執(zhí)行attach()方法的時候會將events()方法中返回的事件句柄綁定,這樣做達到方面管理和擴展的目的。比如CModelBehavior中將model相關的事件集中起來,便于其子類的復用,當我們需求為model添加行為的時候可以繼承它。
以上就是本文的全部內容,希望對大家的學習有所幫助,更多相關內容請關注PHP !
相關推薦:
關于yii分頁組件的用法
關于Yii數(shù)據(jù)模型中rules類驗證器的用法
以上就是對于Yii框架組件和事件行為管理的解析的詳細內容,PHP教程
鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯(lián)系我們修改或刪除,多謝。
新聞熱點
疑難解答