Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

EventListener使いこなし術 - Symfony勉強会#10

3,819 views

Published on

Symfony勉強会#10 の LT枠で発表してきた内容です。
ブログ
http://okapon-pon.hatenablog.com/entry/2014/07/29/015745

Published in: Technology
  • Be the first to comment

EventListener使いこなし術 - Symfony勉強会#10

  1. 1. EventListener 使いこなし術 Symfony 勉強会 #10
 岡田祐一 @okapon_pon
  2. 2. 自己紹介 • 名前:岡田祐一 (@okapon_pon) • 所属:株式会社クロコス エンジニ ア • 2013年∼ 日本Symfonyユーザー会 • Symfony歴 2年半ほど
  3. 3. 本日の話 EventListener使いこなし術 あらため EventListenerできること
  4. 4. まえおき ! Symfonyについて
  5. 5. Symfony ! 素直で柔軟なフレームワーク
  6. 6. Symfony ! HWに縛られず自由に開発できる
  7. 7. Symfony 柔軟性を支える屋台骨 • DI (+ configuration) • Event Dispatcher EventListenerはここの話
  8. 8. Symfony イベント駆動のフレームワーク ! フックポイントが用意されている!
  9. 9. Symfonyのイベント 標準で用意されてるイベント ! • kernel.request • kernel.controller • kernel.view • kernel.response • kernel.exception
  10. 10. Symfonyのイベント 任意のイベントにフック可能 任意のタイミングでResponse を返すことが可能
  11. 11. EventListener 実例 それでは例を見ていきましょう
  12. 12. kernel.controllerイベント kernel.controllerイベント ! コントローラーの実行前に 発行されるイベント
  13. 13. kernel.controllerイベント BeforFilterControllerListener というクラスを作ってみます
  14. 14. kernel.controllerイベント EventLisnerを登録
 # service.yml services: my.blog.before_filter_controller_listener: class: MyBlogBundleEventListenerBeforFilterControllerListener tags: - { name: kernel.event_listener, event: kernel.controller, method: onKernelController }
  15. 15. EventListenerクラス作成 class BeforeFilterControllerListener { public function onKernelController(FilterControllerEvent $event) { $c = $event->getController(); if (!is_array($c)) { return; } $controller = $c[0]; ! if (method_exists($controller, 'before')) { $controller->before($event->getRequest(); } } }
  16. 16. EventListenerクラス作成 何やってるか分かりました?
  17. 17. コントローラー側 /** * @Route("/blog") * @Template() */ class BlogController extends Controller { public function before(Request $request) { // Actionが呼ばれる前に実行したい処理が書ける } ! /** * @Route("/", name="blog_index") */ public function indexAction() { } }
  18. 18. Controller実行前のフック どこかのフレームワークで 見たことある機能・・・
  19. 19. なぜSymfonyにないのか? コントローラーに書くと • 再利用しにくい • テストしづらい
  20. 20. なぜSymfonyにないのか? もう一度コードに戻ります
  21. 21. class BeforeFilterControllerListener { public function onKernelController(FilterControllerEvent $event) { $c = $event->getController(); if (!is_array($c)) { return; } $controller = $c[0]; ! if (method_exists($controller, 'before')) { $controller->before($event->getRequest(); } } } EventListenerクラス作成 コントローラー側に書く必要がないと感じませんか?
  22. 22. EventListener まとめ1 EventListenrに記述した方が変 な依存を持たずシンプルに実装 できる 【サンプルコード】 https://gist.github.com/okapon/fd2dfdacf87e417f7957
  23. 23. EventListener 実装例 Securityコンポーネント よく分からなくて
 昔作ったオレオレ認証
 https://gist.github.com/okapon/ 88f5bd56a886c287a7d1
  24. 24. EventListener 実装例 先ほどの実装例では isSecure()メソッドはマーカー → annotationにするとよい ! 【参考】Doctrine-Common-Annotations http://docs.doctrine-project.org/projects/doctrine-common/en/ latest/reference/annotations.html
  25. 25. EventListener まとめ2 ユーザー認証の仕組みも EventListenrを使えば 簡単に実装できる
  26. 26. ちなみに ここまでkernel.controllerを取 り上げといてなんですが・・・ よく使うのは • kernel.request • kernel.response
  27. 27. では気を取り直して
  28. 28. EventListener使いどころ 複数コントローラーで実行したい共通処理 • 認証まわり • 初回登録時のアクセス判定 • チュートリアルの完了状態で表示出し分け • アクセスの分析(referrerとか)
  29. 29. チュートリアルの表示判定する例 ユーザーはどこのURLにでもアクセ スする可能性がある ! • kernel.requestをフック • EventListenerでチュートリアル完了か判定 • 完了してなければチュートリアルを表示
  30. 30. TutorialListener実装例1 class TutorialListener { public function onKernelRequest(GetResponseEvent $event) { if (HttpKernelInterface::MASTER_REQUEST !== $event- >getRequestType()) { return; } if (!$this->securityContext->getToken()) { return; } ! $user = $this->securityContext->getToken()->getUser(); if ($this->doseNeedTutorial($user)) { // チュートリアルのURLにリダイレクトするとか $event->setResponse(new RedirectResponse('/tutorial', 302)); } } }
  31. 31. TutorialListener実装例2 class TutorialListener { public function onKernelRequest(GetResponseEvent $event) { if (HttpKernelInterface::MASTER_REQUEST !== $event- >getRequestType()) { return; } if (!$this->securityContext->getToken()) { return; } ! $user = $this->securityContext->getToken()->getUser(); if ($this->doseNeedTutorial($user)) { // sessionに状態を入れるとか $this->session->set(’needTutorial’, true)); } } }
  32. 32. アクセスデータの収集に使う例 ! • どこからアクセスされたかreferrerを取る • sessionに保存 • 必要なタイミングでsessionから取出し保存
  33. 33. アクセスデータの収集に使う例 use SymfonyComponentHttpKernelHttpKernelInterface; use SymfonyComponentHttpKernelEventGetResponseEvent; ! class AccessLogListener { public function onKernelRequest(GetResponseEvent $event) { if (HttpKernelInterface::MASTER_REQUEST !== $event- >getRequestType()) { return; } $request = $event->getRequest(); ! // あくまでrefを取るだけのサンプル // 実際には各種属性情報を保存しとくと良い $ref = $request->query->get('ref'); if ($ref) { $request->getSession()->set(‘ref’, $ref); } } }
  34. 34. まとめ(無理矢理) ! • コントローラ実行前の共通処理を書くの に便利 • EventListener使えばアイデア次第で色々 ハックできる • オレオレ作ってしまってもいいじゃない
  35. 35. EventListener おまけ 活用事例としてはbrtriverさんのお話 が非常に参考になります ! 「運用しやすい管理画面とは」 http://tech.voyagegroup.com/archives/7644534.html ! "PHP Fatal error: Allowed memory size of xxx" で落ちる前にできること http://d.hatena.ne.jp/brtRiver/20131206/1386345547

×