Yii Framework Analysis (II)-CComponent class analysis
Yii is a component-based web framework. the CComponent class is the base class of all components.
The CComponent class provides the property-based, event, and behavior-based programming interfaces for child classes.
1. component properties)
The Ccomponent class does not provide attribute variable storage. it must be implemented by subclass using two methods. The getPropertyName () method of the subclass provides the value operation data of $ component-> PropertyName, and the setPropertyName ($ val) method of the subclass provides the value assignment operation of $ component-> PropertyName.
$ Width = $ component-> textWidth ;???? // Get the textWidth attribute
Implementation Method: Call the subclass method $ width = $ component-> getTextWidth ()
$ Component-> textWidth = $ width ;???? // Set the textWidth attribute
Implementation Method: Call the subclass method $ component-> setTextWidth ($ width)
public function getTextWidth(){ return $this->_textWidth;}public function setTextWidth($value){ $this->_textWidth=$value;}
The component property value is case-insensitive (class members are case-insensitive)
2. component events)
A component event is a special attribute. it can register (bind) an event processing handle (function name, class method, or object method) to an event name, the handle is automatically called when an event is triggered.
Component events are stored in the $ _ e [] array of CComponent. The key value of the array is the name of the event, and the key value is a Clist object, clist is a queue container provided by Yii. the Clist method add () adds the callback handle of the event.
// Add a global function to Event Processing
$ Component-> onBeginRequest = "logRequest ";
// Add a static class method to Event Processing
$ Component-> onBeginRequest = array ("CLog", "logRequest ");
// Add an object method to Event Processing
$ Component-> onBeginRequest = array ($ mylog, "logRequest ");
Call events:
$ Component-> raiseEvent ('onininrequest', $ event );
Will be called automatically:
LogRequest ($ event), Clog: logRequest ($ event) and $ mylog. logRequest ($ event)
The event handle must be defined as follows:
Function methodName ($ event)
{
......
}
The $ event parameter is an instance of CEvent or its subclass. it contains at least "who has suspended this event" information.
The event name starts with "on". In _ get () and _ set (), you can use this to differentiate attributes and events.
3. behavior)
The behavior of a component is a way to extend the function of the component without inheritance (see the rule mode in the design mode ).
The behavior class must implement the IBehavior interface. most behavior can be extended from the CBehavior base class.
The IBehavior interface provides four methods.
Attach ($ component) associates itself with the component, detach ($ component) disassociates $ component, getEnabled () and setEnabled () sets the validity of the behavior object.
The behavior object is stored in the $ _ m [] array of the component. the array key value is the behavior name string, and the array value is the behavior class object.
The component extends an action by using attachBehavior ($ name, $ behavior:
$ Component-> attachBehavior ('render', $ htmlRender)
Added a render behavior for $ component. $ htmlRender must be an object that implements the IBehavior interface or an array:
array( ‘class’=>’path.to.BehaviorClass’, ‘property1′=>’value1′, ‘property2′=>’value2′,* )
The behavior object is created based on the class of the array and the attribute value is set.
$ HtmlRender is stored in $ _ m ['render.
When an undefined method of a component is called externally, the magic method _ call ()? It traverses all behavior objects. if a method with the same name is found, it is called.
For example? $ HtmlRender? Is there a method? RenderFromFile () can be accessed directly as a component method:
$ Component-> renderFromFile ()
4. CComponent source code analysis
// Base class CComponent {private $ _ e; private $ _ m; // magic method public function _ get ($ name) {$ getter = 'get '. $ name; // whether the get method of the attribute exists if (method_exists ($ this, $ getter) return $ this-> $ getter (); // starts with on, get Event Processing handle else if (strncasecmp ($ name, 'on', 2) ===0 & method_exists ($ this, $ name )) {// Event name Lower case $ name = strtolower ($ name); // if _ e [$ name] does not exist, an empty CList event handle queue object if (! Isset ($ this-> _ e [$ name]) $ this-> _ e [$ name] = new CList; // return the return $ this-> _ e [$ name] handle queue object stored in _ e [$ name];} // if the behavior object is stored in _ m [$ name], else if (isset ($ this-> _ m [$ name]) is returned. return $ this-> _ m [$ name]; else throw new CException (Yii: t ('yii', 'Property "{class }. {property} "is not defined. ', array (' {class} '=> get_class ($ this),' {property} '=> $ name )));} /*** PHP magic method * set the attributes and events of the component */public function _ set ($ na Me, $ value) {$ setter = 'set '. $ name; // set method if (method_exists ($ this, $ setter) $ this-> $ setter ($ value); // name starts with on, this is the event processing handle else if (strncasecmp ($ name, 'on', 2) ===0 & method_exists ($ this, $ name )) {// Event name Lower case $ name = strtolower ($ name); // _ e [$ name] if (! Isset ($ this-> _ e [$ name]) $ this-> _ e [$ name] = new CList; // add an event processing handle $ this-> _ e [$ name]-> add ($ value);} // The attribute does not have the set method, only the get method, which is a read-only attribute, thrown exception else if (method_exists ($ this, 'get '. $ name) throw new CException (Yii: t ('yii', 'Property "{class }. {property} "is read only. ', array (' {class} '=> get_class ($ this),' {property} '=> $ name); else throw new CException (Yii :: t ('yii', 'Property "{class }. {property} "is not defined. ', Rray ('{class}' => get_class ($ this), '{property}' => $ name )));} /*** PHP magic method * provides the isset () function with a judgment on the existence of attributes and event processing handle */public function _ isset ($ name) {$ getter = 'get '. $ name; if (method_exists ($ this, $ getter) return $ this-> $ getter ()! = Null; else if (strncasecmp ($ name, 'on', 2) === 0 & method_exists ($ this, $ name )) {$ name = strtolower ($ name); return isset ($ this-> _ e [$ name]) & $ this-> _ e [$ name]-> getCount ();} else return false ;} /*** PHP magic method * set the property value to null or delete the processing handle corresponding to the event name */public function _ unset ($ name) {$ setter = 'set '. $ name; if (method_exists ($ this, $ setter) $ this-> $ setter (null); else if (strncasecmp ($ name, 'on', 2) ===0 & method_exi Sts ($ this, $ name) unset ($ this-> _ e [strtolower ($ name)]); else if (method_exists ($ this, 'get '. $ name) throw new CException (Yii: t ('yii', 'Property "{class }. {property} "is read only. ', array (' {class} '=> get_class ($ this),' {property} '=> $ name);}/*** PHP magic method *? CComponent undefined class method: find the same name method in the behavior class and call the behavior method */public function _ call ($ name, $ parameters) {// The $ _ m array of the behavior class is not empty if ($ this-> _ m! = Null) {// cyclically retrieve the behavior class foreach ($ this-> _ m as $ object) stored in the $ _ m array {// The behavior class object is valid, if ($ object-> enabled & method_exists ($ object, $ name) return call_user_func_array (array ($ object, $ name ), $ parameters) ;}} throw new CException (Yii: t ('yii', '{class} does not have a method named "{name }". ', array (' {class} '=> get_class ($ this),' {name} '=> $ name )));} /*** return the behavior class object according to the behavior name */public function asa ($ behavior) {r Eturn isset ($ this-> _ m [$ behavior])? $ This-> _ m [$ behavior]: null;}/*** Attaches a list of behaviors to the component. * Each behavior is indexed by its name and shocould be an instance *? {@ Link? IBehavior}, a string specifying the behavior class, or an * array of the following structure :* * array( *???? ‘class’=>’path.to.BehaviorClass’, *???? ‘property1′=>’value1′, *???? ‘property2′=>’value2′, * ) *
* @ Param array list of behaviors to be attached to the component * @ since 1.0.2 */public function attachBehaviors ($ behaviors) {// $ behaviors is an array $ name =>$ behavior foreach ($ behaviors as $ name =>$ behavior) $ this-> attachBehavior ($ name, $ behavior );} /*** add an action to the component */public function attachBehavior ($ name, $ behavior) {/* $ behavior is not an instance of the IBehavior interface, * array (*???? 'Class' => 'path. to. behaviorclass ',*???? 'Property1' => 'value1 ′,*???? 'Property2' => 'value2', *) * passed to Yii: createComponent creation behavior and initialized object attributes */if (! ($ Behavior instanceof IBehavior) $ behavior = Yii: createComponent ($ behavior); $ behavior-> setEnabled (true); $ behavior-> attach ($ this ); return $ this-> _ m [$ name] = $ behavior;}/*** Raises an event. * This method represents the happening of an event. it invokes * all attached handlers for the event. * @ param string the event name * @ param CEvent the event parameter * @ throws CException if the event is und Efined or an event handler is invalid. */public function raiseEvent ($ name, $ event) {$ name = strtolower ($ name ); // _ e [$ name] if (isset ($ this-> _ e [$ name]) exists in the event processing handle queue. {// cyclically retrieve the event processing handle foreach ($ this-> _ e [$ name] as $ handler) {// The event Processing handle is the global function if (is_string ($ handler) call_user_func ($ handler, $ event); else if (is_callable ($ handler, true )) {// an array: 0-object, 1-method name list ($ object, $ method) = $ handler; If (is_string ($ object ))? // Static class method call_user_func ($ handler, $ event); else if (method_exists ($ object, $ method) $ object-> $ method ($ event ); else throw new CException (Yii: t ('yii', 'event "{class }. {event} "is attached with an invalid handler" {handler }". ', array (' {class} '=> get_class ($ this),' {event} '=> $ name, '{handler}' => $ handler [1]);} else throw new CException (Yii: t ('yii', 'event "{class }. {event} "is attached with an invalid han Dler "{handler }". ', array (' {class} '=> get_class ($ this),' {event} '=> $ name, '{handler}' => gettype ($ handler )))); // if ($ event instanceof CEvent) & amp; $ event-> handled) return ;}} else if (YII_DEBUG &&! $ This-> hasEvent ($ name) throw new CException (Yii: t ('yii', 'event' {class }. {event} "is not defined. ', array (' {class} '=> get_class ($ this),' {event} '=> $ name )));}}