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". [] []
・
・
・