Event Listeners.

Symfony2の便利機能の1つであるイベントリスナーについて.

イベントの定義

ログ出力や例外処理などをコーディングせずに、共通処理としてイベント化.

適当なバンドルで、BeforeFilterControllerListnerクラス作成.

そのイベントリスナークラスを動作させるために、以下services.ymlファイルを定義.

parameters:
     event.class: Test\TestBundle\EventListener\BeforeFilterControllerListner

services:
     test_test.sampleEvent:
         class: %event.class%
         arguments: ["@service_container"]
         tags:
             - { name: kernel.event_listener, event: test.event, method: onEventOccur }
             - { name: kernel.event_listener, event: kernel.terminate, method: onKernelTerminate }          

tagsでイベントの内容を登録.

1つ目のイベントは独自で作成したイベント.

2つめのイベントはカーネルの処理終了時に実行.

リスナークラスを定義

以下メソッドを定義.

・services.ymlで定義した任意タイミングでの呼び出し可能なonEventOccurメソッド.

・処理終了時に呼び出されるonKernelTerminateメソッド

namespace Test\TestBundle\EventListener;

use Symfony\Component\HttpKernel\Event\PostResponseEvent;
use Symfony\Component\EventDispatcher\GenericEvent;

class BeforeFilterControllerListner 
{
    private $_container;

    public function __construct($container)
    {
        $this->_container = $container;
    }

    /**
     * 指定箇所でイベント発生
     */
    public function onEventOccur(GenericEvent $event)
    {
        $logger = $this->_container->get('logger');
        $logger->info('Test Event Occur!!');
    }

    /**
     * リクエスト終了時のイベント処理
     */
    public function onKernelTerminate(PostResponseEvent $event)
    {
        $logger = $this->_container->get('logger');
        $logger->info('Test Listner Terminate!!');
    }
}

処理内容はどちらもログ出力.

今回はdev環境で動作確認しapp/logs配下のdev.logに出力される.

コントローラクラス実装

処理終了時は勝手にイベントが呼ばれる.

任意タイミングでの呼び出しは自分でイベントを作成してディスパッチする必要がある.

namespace Test\TestBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\EventDispatcher\GenericEvent;

/**
 * コントローラクラス
 */
class DefaultController extends Controller
{
    public function index2Action()
    {
        /**
         * イベントディスパッチ
         */
        $dispatcher = $this->container->get('event_dispatcher');
        $event = new GenericEvent("test.event");
        $dispatcher->dispatch("test.event", $event);

        return new JsonResponse(array("result"=>"Successful"), JsonResponse::HTTP_OK);
    }
}

上記ロジックを呼び出すと以下のようにログ出力される↓↓↓

[2015-10-06 14:01:01] request.INFO: Matched route "test_ivent". {"route_parameters":{"_controller":"Test\\TestBundle\\Controller\\DefaultController::index2Action","_route":"test_ivent"},"request_uri":"http://xxx.xx.xx.xxx/Symfony2/web/app_dev.php/hello2"} []
[2015-10-06 14:01:01] security.INFO: Populated the TokenStorage with an anonymous Token. [] []
・
・
・
[2015-10-06 14:01:01] event.DEBUG: Notified event "kernel.controller" to listener "Sensio\Bundle\FrameworkExtraBundle\EventListener\TemplateListener::onKernelController". [] []
[2015-10-06 14:01:01] app.INFO: Test Event Occur!! [] []
[2015-10-06 14:01:01] event.DEBUG: Notified event "test.event" to listener "Test\TestBundle\EventListener\BeforeFilterControllerListner::onEventOccur". [] []
・
・
・
[2015-10-06 14:01:01] event.DEBUG: Notified event "kernel.finish_request" to listener "Symfony\Component\Security\Http\Firewall::onKernelFinishRequest". [] []
[2015-10-06 14:01:01] app.INFO: Test Listner Terminate!! [] []
[2015-10-06 14:01:01] event.DEBUG: Notified event "kernel.terminate" to listener "Test\TestBundle\EventListener\BeforeFilterControllerListner::onKernelTerminate". [] []
・
・
・
Fin.