A detailed analysis of Eventdispatcher event distribution components in PHP

Source: Internet
Author: User
Tags autoload inheritance php class

Introduction

To consider a problem, now you want to provide a plug-in system for your project, Plug-ins can add some methods, or do something before or after some method is executed without interfering with other plug-ins. To implement this system, simple single inheritance is not a good idea, even if more inheritance in PHP is possible, he also has inherent shortcomings (multiple inheritance is not too familiar, feel pretty fucked).

The Symfony Eventdispatcher implements the broker pattern in a simple and efficient way, and the event distributor is the intermediary that allows the system and plug-ins to not be coupled together, making it possible for the above plug-in system, and he will make your project more scalable.

Above, translated from Symfony official document fragment

System Analysis

Event Storage

The above diagram is an analysis of the Symfony Eventdispatcher component source code, you can see how the event in the system is stored

This stores the event two times and is used to add the concept of priority priority when stored as the above structure in the above figure, take out the following structure from the above figure out, the same event names can have different priority, the higher the priority of the event priority trigger, the same priority, The event that you insert first triggers the priority.

The sort event (the structure below in the previous illustration) is not built when the event is inserted, instead, when you take out an event, you generate a sequence of events, and when you insert a new event in the same event name or delete an event, the corresponding sequence of event names are deleted, and the following are used to reconstruct

When the event is executed, a linster list of corresponding event names is obtained, followed sequentially.

Event Execution

As shown in the figure above, when a certain time is triggered, the event name, if more than one trigger action is monitored, they will be triggered in order of priority, registration sequence, triggering action is generally an executable "instance" (whether it is a class or a function, must be called through Call_user_func_array), You can pass in three parameters, the first argument (must) be an event instance, the second is the triggered event name, and the third is the event dispatcher instance. The first parameter controls whether the event continues to pass between all triggered actions in the name of the event, such as the event.propagationstopped set to true in the linstener_2 above, and the event stops propagating after the linstener_2 is executed. The action behind the linstener_2 does not trigger.

In addition, other necessary information can be saved in the event instance in order to obtain additional information when the linstener triggers execution.

Event subscribers

Event subscriber, tell Dispathcer instance, all the events he wants to subscribe to, without having to register by Dispathcer instance. The event subscriber is a PHP class, and he can tell dispathcer the specific events he wants to subscribe to.

Benefits:

    • The events of concern do not need to be registered.
    • Cancel the attention of the event without having to remove the registration.

The internal concerns of the Subscriber are a whole, either full attention or no attention

instance

Ordinary chestnuts

Include "vendor/autoload.php";
Usesymfony\component\eventdispatcher\eventdispatcher;
Usesymfony\component\eventdispatcher\event;
Classusereventextendsevent
{
Publicfunctionname ()
{
Return "Cartman";
}
Publicfunctionage ()
{
return "24";
}
}
$dispatcher =neweventdispatcher ();
$dispatcher->addlistener ("User.Name", Function ($event, $eventName, $dispatcher) {
echo "My name is cartman\n";
});
$dispatcher->addlistener ("User.Name", Function ($event, $eventName, $dispatcher) {
echo "My name is {$event->name ()} from event instance\n";
}, 10);
$dispatcher->addlistener ("User.age", Function ($event, $eventName, $dispatcher) {
echo "My age is 24\n";
}, 10);
$dispatcher->addlistener ("User.age", Function ($event, $eventName, $dispatcher) {
Echo ' My ' is {$event->age ()} ' from event instance\n ';
},-10);
$dispatcher->dispatch ("User.Name", Newuserevent ());
$dispatcher->dispatch ("User.age", Newuserevent ());

The example above outputs

My name is Cartman from Event instance
My name is Cartman
My age is 24
My age are from Event instance

Event Subscriber Chestnuts

Registering events through subscriber

Include "vendor/autoload.php";
Usesymfony\component\eventdispatcher\eventdispatcher;
Usesymfony\component\eventdispatcher\event;
Usesymfony\component\eventdispatcher\eventsubscriberinterface;
Classbookeventextendsevent
{
Public$name= Self::class;
}
Classbooksubscriberimplementseventsubscriberinterface
{
Publicstaticfunctiongetsubscribedevents ()
{
return[
"Chinese.name" => "Chinesenameshow",
"English.name" => [
["Englishnameshow",-10],
["Englishnameafter", 10],
],
"Math.name" => ["Mathnameshow", 100]
];
}
Publicfunctionchinesenameshow (event$event)
{
echo "I am a Chinese book \ n";
}
Publicfunctionenglishnameshow (event$event)
{
echo "I am an English book \ n";
}
Publicfunctionenglishnameafter (event$event)
{
echo "I am the English book after the show [from the event instance {$event->name}]\n";
}
Publicfunctionmathnameshow (event$event)
{
echo "I am the mathematical Book of the show \ n";
}
}
$dispatcher =neweventdispatcher ();
$subscriber =newbooksubscriber ();
$dispatcher->addsubscriber ($subscriber);
$dispatcher->dispatch ("English.name", Newbookevent ());
$dispatcher->dispatch ("Chinese.name");
$dispatcher->removesubscriber ($subscriber);
$dispatcher->dispatch ("Math.name");

Output as content:

I am the English book after the show [from the event instance Bookevent]
I am an English book
I am a Chinese book

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.