This article can be used as a supplement to "Yii Framework Analysis (2) - CComponent Class Analysis".
The CComponent class provides the foundation for component-based and event-driven programming of the YII framework. Most classes in the YII framework use the CComponent class as a base class. The CComponent class provides 3 features for its subclasses:
1. Member variable expansion
Define a member variable by defining two member functions (getXXX/setXXX), such as:
public function getText() {…}
public function setText {…}
This is equivalent to defining a $text member variable, which can be called like this
$a=new CComponent; $a=$component->text; // 等价于$a=$component->getText(); $component->text='abc'; // 等价于$component->setText('abc');
CComponent uses the magic method __get and __set to implement the "member variable expansion" feature. If a member variable that does not exist in the class itself is operated, PHP will call the __get and __set methods of this class for processing. CComponent uses these two magic methods to implement the "member variable expansion" feature. The following figure describes a subclass of CComponent, which adds two member variables, active and sessionName. The figure describes the calling process of these two member variables.
(Note: Regarding the use of magic methods __get and __set, please refer to: PHP Basics and Objects 13 - Overloading)
In object-oriented programming, it is enough to directly define a member variable. Why does CComponent implement a member variable by defining two functions? One of the main reasons is the need to "delay loading" of member variables. Generally, the member variables of a class are uniformly assigned in the constructor or initialization function, but not every member variable will be assigned during the processing of a web request. For example, the App class defines two member variables: $cache and $db ($cache is a cache object, $db is a database link object). These two objects are created when the App class is initialized, but a web For some pages on the website, the content can be obtained through cache, so the database link object does not actually need to be created. If App is defined as a subclass of CComponent, two methods are defined in the App class: getCache/getDb, so that the getDb function is called to initialize the database link when the db member variable is used for the first time. Implement lazy loading - i.e. initialize on first use. Although delayed loading will add one function call, it can reduce unnecessary initialization of member variables (generally improving the access speed of the website), and can make our code easier to maintain and expand.
Delayed loading should be the most important use of the "member variable expansion" feature. Of course, this feature will have other uses. Think about it, when you operate a member variable, you are actually calling getXXX and setXXX Member function, you are calling a piece of code!
2. Event model
The event model is the "observer pattern" in the design pattern: when the state of an object changes, then this object can notify other objects of the event.
In order to use the event model, these three steps need to be implemented: 1. Define the event; 2. Register the event handler; 3. Trigger the event.
The subclass of CComponent defines an event by defining a member function starting with on, such as: public function onClick(){...}, and then registers the event handler by calling the attachEventHandler member function (multiple event handlers can be registered) , and finally trigger the event by calling raiseEvent.
The CComponent class uses a private member variable to save the event and all handles for processing the event. This member variable can be regarded as a hash table. The key of the hash table is the name of the event, and the value of the hash table is the event processing function linked list. .