(To) Yii component mechanism: CComponent analysis of the component base class. The component mechanism of Yii is the essence of Yii's entire system. before using Yii, you should first understand its component mechanism. if you do not understand this mechanism, read the component mechanism of Yii source Yii.
The component mechanism is the essence of Yii's entire system. before using Yii, you should first understand its component mechanism. if you do not understand this mechanism, it will be very difficult to read the Yii source code. The component mechanism gives the Yii Framework infinite flexibility and scalability. it is no exaggeration to say that the basic structure of the Yii Framework is components. As large as CApplication objects, controllers, and routing manager (urlManager), as small as some other plug-ins, all exist in the form of components.
What is the Yii component?
Almost all classes in Yii that can be instantiated and inherited from CComponent can be called components.
What are the features of components?
It inherits from the CComponent class (directly or indirectly) and has an event and behavior mechanism. you can define its attributes in the configuration file.
How to create a component?
Compile a custom class and inherit from the CComponent class.
The CComponent class is the base class of all components, which is crucial in the Yii Framework. Specifically, this class mainly implements the following three functions:
1. define the attributes of the class by using the magic method _ set and _ get in php. That is to say, in addition to the defined public member attributes, the attributes of a component can also be set and obtained by extending the setXXX and getXXX methods using the functions implemented by CComponent, for some special attributes, we may want to verify that they are in the correct format when setting them, which is useful at this time.
Class webpage extends CComponent {
Public $ title;
Private $ _ url;
Public function setUrl ($ value = ''){
If (is_url ($ value )){
$ This-> _ url = $ value;
}
}
Public function getUrl (){
Return $ this-> _ url;
}
}
$ Page = new webpage ();
$ Page-> title = "page title ";
$ Page-> url = "/index. php"; # call $ page-> seturl ("/index. php ");
Echo $ page-> url # $ page-> geturl ();
That is to say, if a component defines setXXX and getXXX, a common attribute access form can be used outside the class.
2. use setter and getter to bind the event processing interface. The event mechanism is everywhere in Yii, and Yii uses a large number of event mechanisms to call functions between components (observer mode ).
So how can we define an event for a component? Yii specifies an onXX method, called an event, as defined below:
Class form extends CComponent {
Public function onSubmit ($ event ){
$ This-> raiseEvent ('onsubmit ', $ event );
}
}
With the above fixed code, an onStop event is created for the car component. But what is the purpose of binding events? When a component generates a series of events, it notifies its events to the bound objects through the event processor. For example, we want to notify the log component of this event to record the event when the form is submitted.
$ Form = new form ();
$ Form-> attachEventHandler ('onsubmit ', array ($ logOjbect, "saveLog "));
$ Form-> data =$ _ POST;
$ Form-> onSubmit (new CEvent ($ form, array ('data' = >$ _ POST); # activate event execution and call the event processing interface logObject: saveLog
The logObject code may be as follows:
Class logObject {
Public function saveLog ($ event ){
$ Event-> sender ===$ form;
$ Event-> params;
}
}
Obviously, this method is far more flexible than the traditional method, and more advanced in terms of concept.
In addition, you can use the setter method to bind events:
$ Form-> onSubmit = array ($ logOjbect, "saveLog ");
Note: The form class does not define the onSubmit member attribute.
At the same time, Yii implements a mechanism to bind multiple processing interfaces to the same event, similar to addEventListener in JavaScript.
Event Processor Interface ripple, standard in php callback type format, see the following for details: http://php.net/manual/en/language.types.callable.php
For example, the code in Yii CLogRouter: init:
Yii: app ()-> attachEventHandler ('onendrequest', array ($ this, 'processlogs '));
Of course, you can also write Yii: app ()-> onEndRequest = array ($ this, 'processlogs ');
CApplication defines the onEndRequest event:
Public function onEndRequest ($ event ){
If (! $ This-> _ ended ){
$ This-> _ ended = true;
$ This-> raiseEvent ('onendrequest', $ event );
}
}
It is not enough to define the event and bind the processor to the event. you have to activate the event in the appropriate place, such as the logic in the CApplication: run () method:
Public function run (){
If ($ this-> hasEventHandler ('onininrequest '))
$ This-> onBeginRequest (new CEvent ($ this ));
$ This-> processRequest ();
If ($ this-> hasEventHandler ('onendrequest '))
$ This-> onEndRequest (new CEvent ($ this ));
}
To implement the event mechanism of components, you need to define events, bind the event processing interface, and activate events.
Behavior mechanism
The behavior mechanism of yii can be simply considered to be a component that uses the methods or attributes of other objects directly (such as the trait structure introduced by php 5.4, which is similar to the action mechanism)
Trait SayWorld {
Public function sayHello (){
Echo 'Hello world! ';
}
}
Class MyHelloWorld extends Base {
Use SayWorld;
}
$ O = new MyHelloWorld ();
$ O-> sayHello ();
Output hello world!
An action is a special class that defines various events and their processing processes. First, we define a behavior class that includes events and their corresponding methods.
Class MyAppBehavior extends CBehavior {
Public $ status = "app behavior ended .";
Public function events (){
Return array (
'Onendrequest' => 'append', # specifies the appEnd of the call behavior when the onEndRequest event of the component is triggered.
);
}
Public function appEnd ($ event = null ){
Echo get_class ($ this );
}
}
$ App-> attachBehavior ('myapp', 'myappbehavior ');
$ App-> run ();
Echo $ app-> status;
We found that the behavior methods and attributes can be directly used by components.
In another common example, we often need to filter user input content, such as preventing html tags from being input. in this case, we can also consider using behavior mechanisms for processing.
$ Form = new FormModel;
If ($ _ POST ){
$ Form-> attributes =$ _ POST;
$ Form-> attachBehavior ('myfilter', array (
'Class' => '',
'Strip _ tags' => true,
));
$ Form-> filter (new CEvent ($ form ));
}
Class myHtmlFilter extends CBehavior {
Public $ strip_tags = false;
Public function events (){
Return array (
'Filter' => 'filterhtml ',
);
}
Public function filterHtml ($ event ){
If ($ event-> sender instanceof CFormModel ){
$ Input = $ event-> sender-> attributes;
$ Event-> sender-> attributes = $ this-> filter ($ input );
}
}
Public function filter (& $ data ){
Return is_array ($ data )? Array_map (array ($ this, 'filter'), $ data): strip_tags ($ data );
}
}
After the above example, we can find that the behavior method can be run directly using the common component method. I have not yet fully understood the usefulness of my behavior.
(