Acara dan mendengar acara
Semasa pelaksanaan program symfony, sejumlah besar pemberitahuan acara akan dicetuskan. Program anda boleh mendengar pemberitahuan ini dan melaksanakan kod arbitrari sebagai tindak balas.
Acara dalaman yang disediakan oleh Symfony sendiri ditakrifkan dalam KernelEvents
kelas. Himpunan pihak ketiga dan perpustakaan kelas juga akan mencetuskan sejumlah besar acara dan program anda sendiri boleh mencetuskan acara tersuai. KernelEvents
类中。第三方Bundle和类库也会触发大量事件,你自己的程序可以触发自定义事件。
本文展示的所有例子,考虑到一致性,使用了相同的KernelEvents::EXCEPTION事件。在你自己的程序中,你可以使用任何事件,甚至在同一订阅器中(subscriber)混合若干事件。
创建一个事件监听 ¶
监听一个事件最常用的方式是注册一个事件监听(event listener):
// src/AppBundle/EventListener/ExceptionListener.phpnamespace AppBundle\EventListener; use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;use Symfony\Component\HttpFoundation\Response;use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface; class ExceptionListener{ public function onKernelException(GetResponseForExceptionEvent $event) { // You get the exception object from the received event // 你可以从接收到的事件中,取得异常对象 $exception = $event->getException(); $message = sprintf( 'My Error says: %s with code: %s', $exception->getMessage(), $exception->getCode() ); // Customize your response object to display the exception details // 自定义响应对象,来显示异常的细节 $response = new Response(); $response->setContent($message); // HttpExceptionInterface is a special type of exception that // holds status code and header details // HttpExceptionInterface是一个特殊类型的异常,持有状态码和头信息的细节 if ($exception instanceof HttpExceptionInterface) { $response->setStatusCode($exception->getStatusCode()); $response->headers->replace($exception->getHeaders()); } else { $response->setStatusCode(Response::HTTP_INTERNAL_SERVER_ERROR); } // Send the modified response object to the event // 发送修改后的响应对象到事件中 $event->setResponse($response); }}
每一个事件,都要接收“类型略有不同”的$event
对象。对于kernel.exception
事件,这个对象是GetResponseForExceptionEvent。要了解每一个“事件监听”所接收到的“事件对象”之类型,参考KernelEvents,或是你要监听的特定事件之文档。
现在,类被创建了,你只需把它注册成服务,然后通过使用一个特殊的“tag”(标签),告诉Symfony这是一个针对kernel.exception
事件的“监听”:
YAML:# app/config/services.ymlservices: app.exception_listener: class: AppBundle\EventListener\ExceptionListener tags: - { name: kernel.event_listener, event: kernel.exception }
xml:<!-- app/config/services.xml --><?xml version="1.0" encoding="UTF-8" ?><container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> <services> <service id="app.exception_listener" class="AppBundle\EventListener\ExceptionListener"> <tag name="kernel.event_listener" event="kernel.exception" /> </service> </services></container>
php:// app/config/services.php$container ->register('app.exception_listener', 'AppBundle\EventListener\ExceptionListener') ->addTag('kernel.event_listener', array('event' => 'kernel.exception'));
有一个可选的tag属性是method
,它定义了“当事件被触发时,哪个方法要被执行”。默认时,方法的名字是on
+“驼峰事件名”。如果事件是kernel.exception
的话,默认执行的方法则是onKernelException()
。
另有一个可选的tag属性是priority
,它的默认值是0
,用来控制监听被执行的顺序(一个监听器的优先级愈高则愈早被执行)。这在你要“确保某个监听在其他监听之前被执行”时是有用的。Symfony的内部监听,其优先级范围是-255
到255
Buat pendengar acara ¶
// src/AppBundle/EventSubscriber/ExceptionSubscriber.phpnamespace AppBundle\EventSubscriber; use Symfony\Component\EventDispatcher\EventSubscriberInterface;use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;use Symfony\Component\HttpKernel\KernelEvents; class ExceptionSubscriber implements EventSubscriberInterface{ public static function getSubscribedEvents() { // return the subscribed events, their methods and priorities // 返回被订阅的事件,以及它们的方法和属性 return array( KernelEvents::EXCEPTION => array( array('processException', 10), array('logException', 0), array('notifyException', -10), ) ); } public function processException(GetResponseForExceptionEvent $event) { // ... } public function logException(GetResponseForExceptionEvent $event) { // ... } public function notifyException(GetResponseForExceptionEvent $event) { // ... }}#🎜🎜#
#🎜🎜#
$event
objek "jenis yang sedikit berbeza". Untuk acara kernel.exception
, objek ini ialah GetResponseForExceptionEvent a >. Untuk memahami jenis "objek acara" yang diterima oleh setiap "pendengar acara", rujuk KernelEvents< / a>, atau dokumen untuk acara khusus yang anda mahu dengar. #🎜🎜##🎜🎜##🎜🎜##🎜🎜##🎜🎜#Sekarang kelas itu dicipta, anda hanya perlu mendaftarkannya sebagai perkhidmatan dan kemudian mendaftarkannya sebagai perkhidmatan dengan menggunakan "tag" khas ( teg), memberitahu Symfony bahawa ini ialah "pendengar" untuk acara
kernel.exception
: #🎜🎜#PHP:// app/config/services.php$container ->register( 'app.exception_subscriber', 'AppBundle\EventSubscriber\ExceptionSubscriber' ) ->addTag('kernel.event_subscriber');
XML:<!-- app/config/services.xml --><?xml version="1.0" encoding="UTF-8" ?><container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> <services> <service id="app.exception_subscriber" class="AppBundle\EventSubscriber\ExceptionSubscriber"> <tag name="kernel.event_subscriber"/> </service> </services></container>
YAML:# app/config/services.ymlservices: app.exception_subscriber: class: AppBundle\EventSubscriber\ExceptionSubscriber tags: - { name: kernel.event_subscriber }#🎜🎜#Atribut teg pilihan ialah
kaedah
, yang mentakrifkan "kaedah mana yang akan dilaksanakan apabila acara dicetuskan." Secara lalai, nama kaedah adalah on
+"nama acara kes unta". Jika acara ialah kernel.exception
, kaedah pelaksanaan lalai ialah onKernelException()
. #🎜🎜##🎜🎜#Atribut teg pilihan lain ialah
0
, yang digunakan untuk mengawal pelaksanaan perintah pemantauan ( lebih tinggi keutamaan pendengar, lebih awal ia akan dilaksanakan). Ini berguna apabila anda ingin memastikan pendengar dilaksanakan sebelum pendengar lain. Pendengar dalaman Symfony mempunyai julat keutamaan daripada -255
hingga 255
, tetapi pendengar anda sendiri boleh menggunakan sebarang integer positif atau negatif. #🎜🎜##🎜🎜##🎜🎜#Buat langganan acara ¶
Cara lain untuk mendengar acara ialah pelanggan acaraLangganan acara, iaitu kelas yang mentakrifkan satu atau lebih kaedah untuk mendengar satu atau lebih acara. Perbezaan utama dengan mendengar acara ialah pelanggan sentiasa mengetahui acara yang mereka dengar.
Dalam pelanggan tertentu, kaedah yang berbeza boleh mendengar acara yang sama. Urutan kaedah dilaksanakan ditakrifkan oleh parameter priority
dalam setiap kaedah (semakin tinggi keutamaan, lebih awal kaedah dipanggil). Untuk mengetahui lebih lanjut tentang pelanggan, rujuk komponen EventDispatcherpriority
参数来定义(优先级愈高则方法愈早被调用)。要了解更多关于订阅器的内容,参考EventDispatcher组件。
下例展示了一个事件订阅,定义了若干方法,监听的是同一个kernel.exception
事件:
// src/AppBundle/EventListener/RequestListener.phpnamespace AppBundle\EventListener; use Symfony\Component\HttpKernel\Event\GetResponseEvent;use Symfony\Component\HttpKernel\HttpKernel;use Symfony\Component\HttpKernel\HttpKernelInterface; class RequestListener{ public function onKernelRequest(GetResponseEvent $event) { if (!$event->isMasterRequest()) { // don't do anything if it's not the master request // 如果不是主请求,就什么也不做 return; } // ... }}
现在,你只需把这个类注册成服务,并打上kernel.event_subscriber
.
kernel.exception
yang sama: 1
Sekarang, anda hanya perlu mendaftar kelas ini sebagai perkhidmatan dan tandakan < code tag >kernel.event_subscriber boleh memberitahu Symofny bahawa ini adalah pelanggan acara:
$ php bin/console debug:event-dispatcher
1
$ php bin/console debug:event-dispatcher kernel.exception
Permintaan acara, semak Jenis ¶
Satu halaman boleh menjana beberapa permintaan (permintaan utama [ permintaan induk], dan kemudian berbilang sub-permintaan [sub-permintaan], biasanya seperti Cara membenamkan pengawal dalam templat). Untuk acara teras Symfony, anda mungkin ingin menyemak sama ada acara itu adalah permintaan "utama" atau permintaan "sub":
rrreee
sebenar, mungkin tidak diperlukan Dilakukan dalam pendengaran daripada subpermintaan.
Mendengar atau melanggan
¶Pendengar dan pelanggan mungkin mempunyai sempadan yang kabur apabila digunakan dalam program yang sama. Memutuskan yang mana satu untuk digunakan selalunya bergantung kepada citarasa peribadi. Walau bagaimanapun, masing-masing mempunyai kelebihan tersendiri:
- Pelanggan mudah digunakan semula
kerana kandungan yang berkaitan dengan acara itu berada di dalam kelas, bukan dalam definisi perkhidmatan. Ini menyebabkan Symfony menggunakan pelanggan secara dalaman;
kerana berkas boleh menghidupkan atau mematikannya secara bersyarat, berdasarkan "nilai pilihan" tertentu dalam fail konfigurasi.
Nyahpepijat pendengar acara
¶rrreee |
Dengan menyatakan nama acara, anda boleh mendapatkan pendengar mendaftar untuk acara khusus ini:
rrreee | rrreee |