: This article mainly introduces Yii2's in-depth study-yiibaseEvent class. For more information about PHP tutorials, see. 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 () */publicstaticfunction on ($ class, $ name, $ h Andler, $ 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. ** This me Thod 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 ()*/ Publicstaticfunction off ($ class, $ name, $ handler = null) {$ class = ltrim ($ class, '\'); if (empty (self :: $ _ events [$ name] [$ class]) {// The event returnfalse does not exist;} if ($ handler = null) {// if handler is empty, this event is directly removed under this class, that is, the unset (self: $ _ events [$ name] [$ class]) event with this name is removed; returntrue ;} else {$ removed = false; // if $ handler is not empty, loop $ _ events to find the corresponding handler and only remove the array foreach (self :: $ _ events [$ n Ame] [$ 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 als O 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. */publicstaticfunction hasHandlers ($ class, $ name) {if (empty (self: $ _ eve Assets [$ name]) {// returns returnfalse;} 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 until it is found or has no parent class. do {if (! Empty (self ::$ _ events [$ name] [$ class]) {returntrue ;}} while ($ class = get_parent_class ($ class ))! = False); returnfalse;}/*** 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 even T parameter. if not set, a default [[Event] object will be created. */publicstaticfunction 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 = newstatic;} // 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 is sende If r is blank, $ 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 ($ linoleic Ss ))! = 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.
The above introduces Yii2's in-depth study-yii \ base \ Event class, including some content, hope to be helpful to friends who are interested in PHP tutorials.