您好,登錄后才能下訂單哦!
這篇文章主要介紹Yii框架組件和事件行為管理的示例分析,文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!
具體如下:
Yii是一個(gè)基于組件、用于開(kāi)發(fā)大型 Web 應(yīng)用的高性能 PHP 框架。CComponent幾乎是所有類(lèi)的基類(lèi),它控制著組件與事件的管理,其方法與屬性如下,私有變量$_e數(shù)據(jù)存放事件(evnet,有些地方叫hook),$_m數(shù)組存放行為(behavior)。
組件管理
YII是一個(gè)純oop框架,很多類(lèi)中的成員變量的受保護(hù)或者私有的,CComponent中利用php中的魔術(shù)方法__get(),__set()來(lái)訪(fǎng)問(wèn)和設(shè)置屬性,但這些方法的作用遠(yuǎn)不指這些。下面用__get()來(lái)說(shuō)明
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))); }
當(dāng)CComponent或者其子類(lèi)對(duì)象實(shí)例$obj->name的時(shí)候,__get($name)方法:
1、首先判斷實(shí)例中是否有g(shù)etName()方法,如果有則返回 ,如果沒(méi)有執(zhí)行第2步
2、判斷是否是以on開(kāi)頭的,以on開(kāi)頭的一般都是CComponent子類(lèi)中預(yù)留的事件,用與掛在事件,通過(guò)method_exists($this,$name)判斷該name是否存在類(lèi)的實(shí)例中,如果存在,返回事件,否則執(zhí)行第3步
3、如果name存在行為數(shù)組中,返回改行為,如果不存在,執(zhí)行第4步
4、遍歷行為數(shù)組,數(shù)組中行為是CBehavior子類(lèi)的實(shí)例,而CBehavior又是CComponent中子類(lèi),所以用遞歸的方法獲取行為中的方法,如果沒(méi)有,執(zhí)行第5步
5、拋出異常:請(qǐng)求的屬性不存在。
在CComponent子類(lèi)中可以重載__get()方法,如在CModule中加入了獲取組件的判斷。這就注意一個(gè)問(wèn)題了屬性和組件名最好不要重名,因?yàn)槌绦驎?huì)優(yōu)先加載組件,可能得到的不是我們想要的屬性,如果必須重名的話(huà),就要用getter獲取屬性。
public function __get($name) { if($this->hasComponent($name)) return $this->getComponent($name); else return parent::__get($name); }
關(guān)于組件的加載與創(chuàng)建,上篇YII框架分析筆記1:YII執(zhí)行流程中的第3點(diǎn)中有個(gè)疑問(wèn):注冊(cè)框架核心組件的時(shí)候一下子加載這么多,是不是影響性能呢?其實(shí)沒(méi)有,注冊(cè)的時(shí)候只是把組件和其對(duì)應(yīng)的配置用鍵值對(duì)的形式保存在數(shù)組中(預(yù)加載的除外),當(dāng)用到時(shí)候才像上面那樣去創(chuàng)建組件,會(huì)通過(guò)YIIBase中的createComponent()方法創(chuàng)建,并初始化。通過(guò)CModule或其子孫類(lèi)(如CWebApplication)調(diào)用__get()或getComponent()獲取組件時(shí),CModule通過(guò)$_components數(shù)組建立對(duì)象池,確保每個(gè)組件在一次請(qǐng)求中只實(shí)例化一次。
事件行為管理
事件相當(dāng)于對(duì)一個(gè)組件的擴(kuò)展或者插件,以組件中預(yù)留的鉤子實(shí)現(xiàn)組件內(nèi)部調(diào)用外部、外部對(duì)組件部分控制。在CComponent子類(lèi)中可以定義以on開(kāi)頭的方法為事件,類(lèi)似于js中的onclick、onchange等,其實(shí)原理差不多。所有事件是與CComponent在同一文件中CEvent的子類(lèi)。
/** * 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中調(diào)用run()方法在處理請(qǐng)求之前先判斷外部是否傳人onBeginRequest事件的句柄,如果有則通過(guò)onBeginRequest($event)方法調(diào)用CComponent中的raiseEvent()方法執(zhí)行句柄中的函數(shù)或者方法。
行為是事件的升級(jí)版,所有的行為都是CBehavior的子類(lèi)。分析上面的__get()方法分析第4步可以看出來(lái)行為的作用是完全擴(kuò)展組件的特性,可以是屬性、方法、事件甚至行為,這樣使程序開(kāi)發(fā)更加靈活。
行為的另一個(gè)作用是將相似事件句柄放在一起,在行為執(zhí)行attach()方法的時(shí)候會(huì)將events()方法中返回的事件句柄綁定,這樣做達(dá)到方面管理和擴(kuò)展的目的。比如CModelBehavior中將model相關(guān)的事件集中起來(lái),便于其子類(lèi)的復(fù)用,當(dāng)我們需求為model添加行為的時(shí)候可以繼承它。
以上是“Yii框架組件和事件行為管理的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對(duì)大家有幫助,更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。