


Symfony2 EventDispatcher component, eventdispatcher_PHP tutorial
Symfony2 EventDispatcher component, eventdispatcher
In a plug-in system, plug-in A can add new methods without affecting other plug-ins, or do some preparation work before running a method, by It is not easy to implement extensions through inheritance. Due to the relationship between plug-ins, changes to plug-in A will also cause the associated plug-ins to be passively modified. Symfony2's EventDispatcher component implements the mediator mode and realizes the decoupling and association between plug-ins. For example, in the HttpKernel component, once the Response is created, it is necessary and useful to allow other modules of the system to modify it when the Response is sent to the client (for example: adding a cache field to the header). The Symfony2 kernel dispatches the kernel.response event, and the listener listening to the event can modify the Response object: a) The listener (PHP object) tells a specific dispatcher class that it wants to listen to the kernel.response event; b) At a certain moment, Symfony will tell the dispatcher to schedule the kernel.response event and pass an Event object containing the Response object into the event dispatch method EventDispatcher::dispatch() c) The dispatcher notifies all listeners listening to the kernel.response event to run, allowing these listeners to modify the Response object. How to use Events When an event is scheduled, the event will have a unique name (for example: kernel.response) and can be listened to by any number of listeners. Instantiate an Event object at the same time and pass it to all listeners. As you will see later, the Event object contains data about the scheduled event. Naming convention The event name can be any string, but it can follow the following naming conventions: * Use only lowercase characters, numbers, dots, and underscores; * Use the prefix name with a dot; * The name of the closing part uses a verb that can express the behavior of the current event; Event name and event object When the dispatcher dispatches an event to notify the listener, it will pass an Event object as a parameter to the listener. The base class Event is very simple, with only one method to stop the event from being passed to the next listener, and not much else. Usually, the data of a specific event will be saved in the Event object to facilitate passing the data to the listener. In the kernel.response event, the Event object passed to the listener is an object of the subclass FliterResponseEvent, which is a subclass of Event. FliterResponseEvent contains getReponse and setResponse methods, allowing the listener to obtain or modify the Response object. In summary: When creating a listener that listens to a specific event, a subclass of Event will be passed into the listener, and the listener can obtain and modify information through the methods of the subclass. Event dispatcher (dispatcher) Dispatcher is the core of the event scheduling system. Generally speaking, a dispatcher contains a list of listeners. When an event needs to be dispatched, the dispatcher will notify all the listeners it contains that are listening to the event.<span>1</span> <span>use Symfony\Component\EventDispatcher\EventDispatcher; </span><span>2</span> <span>3</span> $dispatcher = <span>new</span> EventDispatcher();
<span>1</span> $listener = <span>new</span><span> AcmeListener(); </span><span>2</span> $dispatcher->addListener(<span>'</span><span>foo.action</span><span>'</span>, array($listener, <span>'</span><span>onFooAction</span><span>'</span>));
PHP callable是指能作为参数传入call_user_func()或者传入is_callable()函数执行后返回true的PHP 变量。PHP callable可以是 \Closure实例,一个实现了__invoke方法的对象,或者是表示一个函数的字符串,或者一个表示对象方法或者类方法的数组。 到目前为止,我们看过把一个PHP对象作为监听器,我们也可以把Closure对象作为监听器。 <pre class="code"><span>1</span> <span>use Symfony\Component\EventDispatcher\Event; </span><span>2</span> <span>3</span> $dispatcher->addListener(<span>'</span><span>foo.action</span><span>'</span>, function (Event $<span>event</span><span>) { </span><span>4</span> <span>//</span><span> will be executed when the foo.action event is dispatched</span> <span>5</span> });
<span> 1</span> <span>use Symfony\Component\EventDispatcher\Event; </span><span> 2</span> <span> 3</span> <span>class</span><span> AcmeListener </span><span> 4</span> <span>{ </span><span> 5</span> <span>//</span><span> ...</span> <span> 6</span> <span> 7</span> <span>public</span> function onFooAction(Event $<span>event</span><span>) </span><span> 8</span> <span> { </span><span> 9</span> <span>//</span><span> ... do something</span> <span>10</span> <span> } </span><span>11</span> }
In actual use, an object of a specific Event subclass is passed to the listener, such as FilterResponseEvent:
<span>1</span> <span>use Symfony\Component\HttpKernel\Event\FilterResponseEvent; </span><span>2</span> <span>3</span> <span>public</span> function onKernelResponse(FilterResponseEvent $<span>event</span><span>) </span><span>4</span> <span>{ </span><span>5</span> $response = $<span>event</span>-><span>getResponse(); </span><span>6</span> $request = $<span>event</span>-><span>getRequest(); </span><span>7</span> <span>8</span> <span>//</span><span> ...</span> <span>9</span> }
<span>namespace</span><span> Acme\StoreBundle; final </span><span>class</span><span> StoreEvents { </span><span>/*</span><span>* * The store.order event is thrown each time an order is created * in the system. * * The event listener receives an * Acme\StoreBundle\Event\FilterOrderEvent instance. * * @var string </span><span>*/</span> <span>const</span> STORE_ORDER = <span>'</span><span>store.order</span><span>'</span><span>; }</span>
<span> 1</span> <span>namespace</span><span> Acme\StoreBundle\Event; </span><span> 2</span> <span> 3</span> <span>use Symfony\Component\EventDispatcher\Event; </span><span> 4</span> <span>use Acme\StoreBundle\Order; </span><span> 5</span> <span> 6</span> <span>class</span><span> FilterOrderEvent extends Event </span><span> 7</span> <span>{ </span><span> 8</span> <span>protected</span><span> $order; </span><span> 9</span> <span>10</span> <span>public</span><span> function __construct(Order $order) </span><span>11</span> <span> { </span><span>12</span> $<span>this</span>->order =<span> $order; </span><span>13</span> <span> } </span><span>14</span> <span>15</span> <span>public</span><span> function getOrder() </span><span>16</span> <span> { </span><span>17</span> <span>return</span> $<span>this</span>-><span>order; </span><span>18</span> <span> } </span><span>19</span> }
<span> 1</span> <span>use Acme\StoreBundle\StoreEvents; </span><span> 2</span> <span>use Acme\StoreBundle\Order; </span><span> 3</span> <span>use Acme\StoreBundle\Event\FilterOrderEvent; </span><span> 4</span> <span> 5</span> <span>//</span><span> the order is somehow created or retrieved</span> <span> 6</span> $order = <span>new</span><span> Order(); </span><span> 7</span> <span>//</span><span> ... </span><span> 8</span> <span> 9</span> <span>//</span><span> create the FilterOrderEvent and dispatch it</span> <span>10</span> $<span>event</span> = <span>new</span><span> FilterOrderEvent($order); </span><span>11</span> $dispatcher->dispatch(StoreEvents::STORE_ORDER, $<span>event</span>);
FilterOrderEvent对象作为参数传入到dispatch方法,现在,任何监听store.order事件的监听器都会接收到FilterOrderEvent对象,并通过调用getOrder方法获得order对象。
<span>1</span> <span>//</span><span> some listener class that's been registered for "store.order" event</span> <span>2</span> <span>use Acme\StoreBundle\Event\FilterOrderEvent; </span><span>3</span> <span>4</span> <span>public</span> function onStoreOrder(FilterOrderEvent $<span>event</span><span>) </span><span>5</span> <span>{ </span><span>6</span> $order = $<span>event</span>-><span>getOrder(); </span><span>7</span> <span>//</span><span> do something to or with the order</span> <span>8</span> }
<span>namespace</span><span> Acme\StoreBundle\Event; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpKernel\Event\FilterResponseEvent; </span><span>class</span><span> StoreSubscriber implements EventSubscriberInterface { </span><span>public</span> <span>static</span><span> function getSubscribedEvents() { </span><span>return</span><span> array( </span><span>'</span><span>kernel.response</span><span>'</span> =><span> array( array(</span><span>'</span><span>onKernelResponsePre</span><span>'</span>, <span>10</span><span>), array(</span><span>'</span><span>onKernelResponseMid</span><span>'</span>, <span>5</span><span>), array(</span><span>'</span><span>onKernelResponsePost</span><span>'</span>, <span>0</span><span>), ), </span><span>'</span><span>store.order</span><span>'</span> => array(<span>'</span><span>onStoreOrder</span><span>'</span>, <span>0</span><span>), ); } </span><span>public</span> function onKernelResponsePre(FilterResponseEvent $<span>event</span><span>) { </span><span>//</span><span> ...</span> <span> } </span><span>public</span> function onKernelResponseMid(FilterResponseEvent $<span>event</span><span>) { </span><span>//</span><span> ...</span> <span> } </span><span>public</span> function onKernelResponsePost(FilterResponseEvent $<span>event</span><span>) { </span><span>//</span><span> ...</span> <span> } </span><span>public</span> function onStoreOrder(FilterOrderEvent $<span>event</span><span>) { </span><span>//</span><span> ...</span> <span> } }</span>
这个监听器类很简单,告诉了dispatcher监听了什么事件,还有监听的事件触发的方法。addSubscriber()方法把subscriber注册到dispatcher。
<span>1</span> <span>use Acme\StoreBundle\Event\StoreSubscriber; </span><span>2</span> <span>3</span> $subscriber = <span>new</span><span> StoreSubscriber(); </span><span>4</span> $dispatcher->addSubscriber($subscriber);
<code>onKernelResponsePre
, <code>onKernelResponseMid
, 和 <code><span>onKernelResponsePost三个方法就会先后执行。</span>
停止事件的传递
在一些情况下,监听器可以停止事件传递下去,防止后续的监听器被调用,换句话说,监听器必须通知dispatcher停止传递事件给后续的监听器。在监听器里面实现stopPropagation()方法:
<span>1</span> <span>use Acme\StoreBundle\Event\FilterOrderEvent; </span><span>2</span> <span>3</span> <span>public</span> function onStoreOrder(FilterOrderEvent $<span>event</span><span>) </span><span>4</span> <span>{ </span><span>5</span> <span>//</span><span> ...</span> <span>6</span> <span>7</span> $<span>event</span>-><span>stopPropagation(); </span><span>8</span> }
<span>1</span> $dispatcher->dispatch(<span>'</span><span>foo.event</span><span>'</span>, $<span>event</span><span>); </span><span>2</span> <span>if</span> ($<span>event</span>-><span>isPropagationStopped()) { </span><span>3</span> <span>//</span><span> ...</span> <span>4</span> }
EventDispatcher is the event sender in as3. This is also a good feature compared to as2. Only objects inherited from this class can send events. dispatchEvent() is the method of sending events. For example, if you create a new object A and you want to notify other objects after certain changes have occurred in this object, you can use dispatchEvent(new Event("yourEvent")) and then you can call A in other places. Add a listener to A
A.addEventListener("yourEvent",yourfunction) This event can be customized, and the general objects are subclasses of EventDispatcher;
The following URL has official and detailed instructions. Please refer to it; help.adobe.com/...r.html
There are two methods: 1. Directly call the object receiving the value in another component through the id and assign a value to it! ex:
import flash.events.EventDispatcher;
/**
* Custom event class for loading data for components
* @author Yuan Jinlong
* @date 2010-07-08
*/
public class LoadDataEvent extends Event
{
public static const dispatcher:EventDispatcher=new EventDispatcher();
public var data:Object = null;
public function LoadDataEvent(type:String, data:Object=null,bubbles: Boolean=false, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
this.EVENT_NAME = type;
this.data = data;
this.typeData = typeData;
this.tempData = tempData;
}
override public function clone():Event{
return new LoadDataEvent(type, bubbles, cancelable, data);
}

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics











In PHP, password_hash and password_verify functions should be used to implement secure password hashing, and MD5 or SHA1 should not be used. 1) password_hash generates a hash containing salt values to enhance security. 2) Password_verify verify password and ensure security by comparing hash values. 3) MD5 and SHA1 are vulnerable and lack salt values, and are not suitable for modern password security.

PHP and Python each have their own advantages, and choose according to project requirements. 1.PHP is suitable for web development, especially for rapid development and maintenance of websites. 2. Python is suitable for data science, machine learning and artificial intelligence, with concise syntax and suitable for beginners.

PHP is widely used in e-commerce, content management systems and API development. 1) E-commerce: used for shopping cart function and payment processing. 2) Content management system: used for dynamic content generation and user management. 3) API development: used for RESTful API development and API security. Through performance optimization and best practices, the efficiency and maintainability of PHP applications are improved.

PHP type prompts to improve code quality and readability. 1) Scalar type tips: Since PHP7.0, basic data types are allowed to be specified in function parameters, such as int, float, etc. 2) Return type prompt: Ensure the consistency of the function return value type. 3) Union type prompt: Since PHP8.0, multiple types are allowed to be specified in function parameters or return values. 4) Nullable type prompt: Allows to include null values and handle functions that may return null values.

PHP is still dynamic and still occupies an important position in the field of modern programming. 1) PHP's simplicity and powerful community support make it widely used in web development; 2) Its flexibility and stability make it outstanding in handling web forms, database operations and file processing; 3) PHP is constantly evolving and optimizing, suitable for beginners and experienced developers.

PHP is mainly procedural programming, but also supports object-oriented programming (OOP); Python supports a variety of paradigms, including OOP, functional and procedural programming. PHP is suitable for web development, and Python is suitable for a variety of applications such as data analysis and machine learning.

Using preprocessing statements and PDO in PHP can effectively prevent SQL injection attacks. 1) Use PDO to connect to the database and set the error mode. 2) Create preprocessing statements through the prepare method and pass data using placeholders and execute methods. 3) Process query results and ensure the security and performance of the code.

PHP and Python have their own advantages and disadvantages, and the choice depends on project needs and personal preferences. 1.PHP is suitable for rapid development and maintenance of large-scale web applications. 2. Python dominates the field of data science and machine learning.
