Yii2: yiibaseEvent class, yii2 -- yii. Yii2's in-depth study-yiibaseEvent class, yii2 -- yii according to the previous article, we know that Yii2 events are divided into two categories: class-level events and instance-level events. Class level Yii2 deep learning-yii \ base \ Event class, yii2 -- yii
According to the previous article, Yii2 events are divided into two categories: class-level events and instance-level events. Class-level events are implemented based on yii \ base \ Event, and instance-level events are implemented based on yii \ base \ Component.
Today, let's take a look at the implementation of class-level events. the code is yii \ base \ Event class.
Sender). 'is inserted .');*});*~~~ ** The handler will be invoked for EVERY successful ActiveRecord insertion. ** For more details about how to declare an event handler, please refer to [[Component: on ()]. ** add events to a class ** @ param string $ class the fully qualified class name to which the event handler needs to attach. * @ param string $ name the event name. * @ param callable $ handler the event handler. * @ param mixed $ data the data To be passed to the event handler when the event is triggered. * When the event handler is invoked, this data can be accessed via [[Event: data]. * @ param boolean $ append whether to append new event handler to the end of the existing * handler list. if false, the new handler will be inserted at the beginning of the existing * handler list. * @ see off () */public static function on ($ class, $ name, $ Handler, $ data = null, $ append = true) {// remove the leftmost slash of the class $ class = ltrim ($ class ,'\\'); // if append is true, put it at the end of the $ _ events array named $ name; otherwise, put it at the beginning if ($ append | empty (self :: $ _ events [$ name] [$ class]) {self: $ _ events [$ name] [$ class] [] = [$ handler, $ data];} else {array_unshift (self: $ _ events [$ name] [$ class], [$ handler, $ data]) ;}} /*** Detaches an event handler from a class-level event. ** Th Is method is the opposite of [[on ()]. ** remove a class event ** @ param string $ class the fully qualified class name from which the event handler needs to be detached. * @ param string $ name the event name. * @ param callable $ handler the event handler to be removed. * If it is null, all handlers attached to the named event will be removed. * @ return boolean whether a handler is found and detached. * @ see on () */Public static function off ($ class, $ name, $ handler = null) {$ class = ltrim ($ class ,'\\'); if (empty (self: $ _ events [$ name] [$ class]) {// This event does not exist return false;} if ($ handler = null) {// If handler is empty, the event will be removed directly under this class, that is, the event unset (self :: $ _ events [$ name] [$ class]); return true;} else {$ removed = false; // if $ handler is not empty, loop $ _ events to find the corresponding handler and only remove the array foreach (self: $ _ Events [$ name] [$ class] as $ I =>$ event) {if ($ event [0] ===$ handler) {unset (self:: $ _ events [$ name] [$ class] [$ I]); $ removed = true ;}} if ($ removed) {// after removal, convert the array into a natural array self: $ _ events [$ name] [$ class] = array_values (self :: $ _ events [$ name] [$ class]);} return $ removed ;}} /*** Returns a value indicating whether there is any handler attached to the specified class-level event. * Note that this Method will also check all parent classes to see if there is any handler attached * to the named event. * checks whether an event exists in a class or object * @ param string | object $ class the object or the fully qualified class name specifying the class-level event. * @ param string $ name the event name. * @ return boolean whether there is any handler attached to the event. */public static function hasHandlers ($ class, $ name) {if (Empty (self: $ _ events [$ name]) {// does not exist. return false directly;} if (is_object ($ class )) {// if it is an object, obtain its class name $ class = get_class ($ class);} else {// if it is a class name, remove the leftmost slash $ class = ltrim ($ class, '\');} // if the class cannot be found, find it in the parent class, do {if (! Empty (self ::$ _ events [$ name] [$ class]) {return true ;}} while ($ class = get_parent_class ($ class ))! = False); return false;}/*** Triggers a class-level event. * This method will cause invocation of event handlers that are attached to the named event * for the specified class and all its parent classes. * trigger an event of a class or object * @ param string | object $ class the object or the fully qualified class name specifying the class-level event. * @ param string $ name the event name. * @ param Event $ event the eve Nt parameter. if not set, a default [[Event] object will be created. */public static function trigger ($ class, $ name, $ event = null) {if (empty (self: $ _ events [$ name]) {return ;} if ($ event = null) {// if the Event does not exist, create an event object $ event = new static;} // Set the attribute of the event object, the default value is unhandled $ event-> handled = false; $ event-> name = $ name; if (is_object ($ class )) {if ($ event-> sender === null) {// if $ class is an object, and If the sender is empty, $ class is assigned to sender, that is, $ class is the object that triggers the event $ event-> sender = $ class ;} $ class = get_class ($ class);} else {$ class = ltrim ($ class, '\');} // $ _ event of the cyclic class, do {if (! Empty (self ::$ _ events [$ name] [$ class]) {foreach (self ::$ _ events [$ name] [$ class] as $ handler) {// assign the parameter to the data attribute of the event object $ event-> data = $ handler [1]; // call the $ handler method // in the method, you can use $ this-> data to get the corresponding parameter // You can also set the value of $ this-> handled in it to interrupt the triggering of subsequent events call_user_func ($ handler [0], $ event); // when a handled is set to true, when this event is executed, it stops and ignores the remaining event if ($ event-> handled) {return ;}}}while ($ class = get_parent_class ($ Class ))! = False );}}
The code above shows that the class-level Event stores the Event in the $ _ events variable of the Event class. When an Event is triggered, you only need to extract it and execute it.
The data structure in $ _ events is roughly as follows:
[ 'add' => [ 'Child' => [ [function ($event) { ... }, $data], [[$object, 'handleAdd'], null], [['ChildClass', 'handleAdd'], $data], ['handleAdd', $data] ], 'ChildClass' => [ ... ] ], 'delete' => [ ... ]]
When we talk about the yii \ base \ Component class, we will talk about instance-level events.
If you are interested in Yii2 source code, you can pay attention to the project yii2-2.0.3-annotated. now you have added a lot of comments about Yii2 source code, and will continue to add ~
If you are interested, you can also participate in the submission of comments from the Yii2 source code.
Category, yii2 -- yii according to the previous article, we know that Yii2 events are classified into two categories: class-level events and instance-level events. Class level...