According to a previous article, we know that the events of Yii2 are divided into two categories, one is class-level events, and the other is instance-level events. Class-level events are based on the yii\base\event implementation, and instance-level events are based on the yii\base\component implementation.
Let's take a look at the implementation of class-level events today, the code is the Yii\base\event class.
Phpnamespace yii\base;/** * Event is the base class for all event classes.*/classEventextendsObject{ /** * @var string the event name. This was set by [[Component::trigger ()]] and [[Trigger ()]]. * Event handlers may use the This property to check the what Event it is handling. * Name of the event*/ Public$name; /** * @var Object The sender of this event. If not set, this property would be * Set as the object whose ' Trigger () "method is called. * Also be a ' null ' if this event is a * Class-level the event which is triggered in a static context. * The object that triggered the event*/ Public$sender; /** * @var Boolean whether the event is handled. Defaults to False. * When a handler sets this to be true, the event processing'll stop and * ignore the rest of the uninvoked event Han Dlers. * Log if the event has been processed, and when handled is set to true, execution to this event will stop and ignore the remaining event*/ Public$handled=false; /** * @var mixed the data that's passed to [[Component::on ()]] When attaching an event handler. * Note that this varies according-which event handler is currently executing. */ Public$data; /** * Store all event, because it is a static property, all event objects/classes share this piece of data*/PrivateStatic$_events= []; /** * Attaches an event handler to a Class-level event. * When a class-level event is triggered, event handlers attached * to that class and all parent classes would be Invoked. * For example, the following code attaches a event handler to ' ActiveRecord ' ' s * ' AfterInsert ' event: * * ~ ~ ~ * Event::on (Activerecord::classname (), Activerecord::event_after_insert, function ($event) {* Yii::tra CE (Get_class ($event->sender). ' is inserted. '); * }); * ~ ~ ~ * The handler is invoked for every successful ActiveRecord insertion. * For more details on how to declare a event handler, please refer to [[Component::on ()]]. * * Add an event to a class * * @param string $class The fully qualified class name to which the event handler needs to Attac H. * @param string $name the event name. * @param callable $handler the event handler. * @param mixed $data The data to being passed to the event handler when the Event is triggered. * When the event handler was invoked, this data can be accessed via [[Event::d ATA]]. * @param boolean $append whether to append new event handler to the end of the existing * handler list. If false, the new handler is inserted at the beginning of the existing * handler list. * @see off ()*/ PublicStaticfunctionOn$class,$name,$handler,$data=NULL,$append=true) { //remove the leftmost slash of class$class=LTrim($class, '\\'); //If Append is true, place the last of the array whose name is $name in $_events, or put it firstif($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 method was the opposite of [[on ()]]. * * Remove the event of a class * * @param string $class The fully qualified class name from which the event handler needs Detached. * @param string $name the event name. * @param callable $handler The event handler to be removed. * IF It is null and all handlers attached to the named event would be removed. * @return Boolean whether a handler is found and detached. * @see on ()*/ PublicStaticfunctionOff$class,$name,$handler=NULL) { $class=LTrim($class, '\\'); if(Empty(Self::$_events[$name][$class])) { //The event does not existreturnfalse; } if($handler===NULL) { //If handler is empty, the event is removed directly under the class, that is, the event of the name is removed.unset(Self::$_events[$name][$class]); returntrue; } Else { $removed=false; //If the $handler is not empty, the loop $_events finds the corresponding handler, removing only the array of handler and dataforeach(Self::$_events[$name][$class] as$i=$event) { if($event[0] = = =$handler) { unset(Self::$_events[$name][$class][$i]); $removed=true; } } if($removed) { //after removal, make the array into a natural array againSelf::$_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 would also check all parent classes to see if there are any handler attached * to the named even T. * detects if a class or object has an event * @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 a handler attached to the event. */ PublicStaticfunctionHashandlers ($class,$name) { if(Empty(Self::$_events[$name])) { //does not exist, returns directlyreturnfalse; } if(Is_object($class)) { //if it is an object, get its class name$class=Get_class($class); } Else { //if it is a class name, remove the leftmost slash of class$class=LTrim($class, '\\'); } //if it is not found in the class, go to the parent class and find it until you find it or have no parent. Do { if(!Empty(Self::$_events[$name][$class])) { returntrue; } } while(($class=Get_parent_class($class)) !==false); returnfalse; } /** * Triggers a class-level event. * This method would cause invocation of event handlers that is attached to the named event * for the specified class A ND all its parent classes. * Triggering 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 event parameter. If not set, a default [[Event]] object would be created. */ PublicStaticfunctionTrigger$class,$name,$event=NULL) { if(Empty(Self::$_events[$name])) { return; } if($event===NULL) { //event does not exist, create an event object$event=NewStatic; } //sets the properties of the event object, which is not handled by default$event->handled =false; $event->name =$name; if(Is_object($class)) { if($event->sender = = =NULL) { //if $class is an object and sender is empty, the $class is assigned to sender, that is, $class is the object that triggered the event$event->sender =$class; } $class=Get_class($class); } Else { $class=LTrim($class, '\\'); } //Loop the $_event of a class until it encounters $event->handled is true or has no parent class Do { if(!Empty(Self::$_events[$name][$class])) { foreach(Self::$_events[$name][$class] as$handler) { //assign a parameter to the event object's Data property$event->data =$handler[1]; //call $handler method//In the method, you can use $this->data to the corresponding parameters//can also be set in which $this->handled Value that interrupts the triggering of subsequent eventsCall_user_func($handler[0],$event); //When a handled is set to true, it stops when it executes to this event and ignores the remaining eventsif($event-handled) { return; } } } } while(($class=Get_parent_class($class)) !==false); }}
As can be seen from the above code, the class-level event, the essence of the event class in the $_events variable to store events, when triggering an event, just take it out, execute it.
The data structure inside the $_events is probably as follows:
[' add ' + = [' child ' = = [ function ($event$ Data], [[$objectnull], [ [$data] , [$data] ], ' childclass ' = [ ... ] , ' delete ' = [ ...] ]]
Later, when we talk about the Yii\base\component class, we'll take a look at instance-level events.
YII2 source interested students can pay attention to the project yii2-2.0.3-annotated, now on the above has been added a lot of comments on Yii2 source code, and then continue to add ~
Interested students can also participate in the submission of YII2 source comments.
The above describes the YII2 in-depth learning--yii\base\event class, including the aspects of the content, I hope that the PHP tutorial interested in a friend helpful.