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.

Laravelの黒魔術 - PHPカンファレンス2020前夜祭

692 views

Published on

Laravelの黒魔術 - PHPカンファレンス2020前夜祭

PHPカンファレンス2020前夜祭の資料です

スライドに貼ったリンクを書いておきます

https://ja.wikipedia.org/wiki/%E3%83%9E%E3%83%BC%E3%82%AB%E3%83%BC%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%95%E3%82%A7%E3%83%BC%E3%82%B9
https://3v4l.org/8gRum
https://laravelplayground.com/#/snippets/9e4449db-6b6c-4794-8b42-05e69d58308c
https://3v4l.org/tunNf
https://readouble.com/laravel/5.4/ja/collections.html
https://laravelplayground.com/#/snippets/06faf2b1-6048-44bf-bec6-d08bb1e8de53

Published in: Engineering
  • Be the first to comment

  • Be the first to like this

Laravelの黒魔術 - PHPカンファレンス2020前夜祭

  1. 1. Laravelの黒魔術 PHP カンファレンス 2020 前夜祭 @localdisk
  2. 2. 名前: localdisk GitHub/twitter: @localdisk 2020/09/01 Togetterに入社しました 趣味はLaravel Livewireです。 自己紹介 2
  3. 3. • インフラエンジニア • https://www.wantedly.com/projects/188299 • PHPエンジニア • https://bosyu.togetter.dev/ • ReactNative/フロントエンドエンジニア • https://rn-bosyu.togetter.dev/ • 学生エンジニア(アルバイト) • https://baito-bosyu.togetter.dev/ We Are Hiring!! 3
  4. 4. We Are Hiring!! 4 なんで!?はひどいと思う
  5. 5. Laravelのソースコードを通して、PHPの様々な実装テクニッ クを紹介します。 「へー。こんなことできるんだ」 と感心したり、困惑したりしてください。 どんなことを話すの? 5
  6. 6. そこそこボリュームがあるため早口かもしれません。 「アイツ Laravelの話になると早口になるの気持ち悪いよ な……」 「しっ よしなよ」 注意 6
  7. 7. スライドは事前公開しますので、スライドを見つつお話をき いていただければ。 (ここにスライドのURL) 聞きたいことがあったら(なくても)Discordでお話しま しょう! #bd-2-laravel-blackmagic にどうぞ! 注意 7
  8. 8. 1. ShouldQueue • マーカーインターフェース 2. Dispacher • デストラクタの活用 3. RealTime Facade • PHP版ダイナミックインポート 4. HigherOrder Messages • マジックメソッドと高階関数の活用 • お品書き 8
  9. 9. ShouldQueue 9 マーカーインターフェース
  10. 10. ShouldQueueの役割 10 リスナをキュー投入するように指定するには、ShouldQueue インターフェイスをリスナクラスに追加します。 <?php // SouldQueueを implements class SendShipmentNotification implements ShouldQueue { // }
  11. 11. ShouldQueue 11 <?php namespace IlluminateContractsQueue; interface ShouldQueue { // } 実装のないインターフェース
  12. 12. Queueに投入するかどうかの判定 12 public function send($notifiables, $notification) { $notifiables = $this->formatNotifiables($notifiables); // instanceof で比較 if ($notification instanceof ShouldQueue) { return $this->queueNotification($notifiables, $notification); } return $this->sendNow($notifiables, $notification); } Instanceof が true なら Queueに投入
  13. 13. マーカーインターフェース 13 マーカーインタフェース (marker interface)とは、オブジェク ト指向プログラミングにおいて、メソッドやフィールドが一切定 義されていないインタフェース。 PHPのSerializableインターフェースもこれ。 https://ja.wikipedia.org/wiki/ %E3%83%9E%E3%83%BC%E3%82%AB%E3%83%BC%E3%82%A4%E3%83%B3%E3 %82%BF%E3%83%95%E3%82%A7%E3%83%BC%E3%82%B9
  14. 14. マーカーインターフェース 14 テクニックとしてはかなり手軽。 色々と使い所が思いつきます。 https://ja.wikipedia.org/wiki/ %E3%83%9E%E3%83%BC%E3%82%AB%E3%83%BC%E3%82%A4%E3%83%B3%E3 %82%BF%E3%83%95%E3%82%A7%E3%83%BC%E3%82%B9
  15. 15. Dispatcher 15 デストラクタの活用
  16. 16. Dispatcherの役割 16 アプリケーションのさまざまな処理を委譲する。 class UserController extends BaseController { public function register() { dispatch(UserRegsitered::class) } }
  17. 17. デストラクタ 17 実処理は __destruct で行われている public function __destruct() { if (! $this->shouldDispatch()) { return; } elseif ($this->afterResponse) { app(Dispatcher::class)->dispatchAfterResponse($this->job); } else { app(Dispatcher::class)->dispatch($this->job); } }
  18. 18. PHPのデストラクタが呼ばれるタイミング 18 • unsetしたとき • nullを代入したとき • 関数のスコープが終了する寸前 つまり参照が外れたときにデストラクタが呼ばれる https://3v4l.org/8gRum
  19. 19. デストラクタ 19 デストラクタを活用すると変数が初期化されたり、関数のス コープが外れる瞬間に自動的に実行することができる。 便利ではあるが…使いどころが難しい
  20. 20. RealTime Facades 20 PHP流ダイナミックインポート
  21. 21. RealTime Facadesの役割 21 アプリケーション内のどんなクラスでもFacadeのように使え るようになる。
  22. 22. RealTime Facades 22 たとえばこんなクラス class Twitter { public function tweet(string $text): void { echo $text; } }
  23. 23. RealTime Facades 23 Namespace の先頭に Facades をつける Route::get('tweet', function () { FacadesTwitter::tweet(‘test'); });
  24. 24. RealTime Facades 24 Twitter クラスを同様の挙動をする 「test」ってでます。 https://laravelplayground.com/#/snippets/ 9e4449db-6b6c-4794-8b42-05e69d58308c Laravel Playground便利ですよ
  25. 25. どのような仕組みなのか? 25 存在しないクラスが require/include された場合PHPはどの ような挙動をするのか? 答えはオートローダーとして登録された関数が呼ばれる。
  26. 26. spl_autoload_register 26 protected function prependToLoaderStack() { spl_autoload_register([$this, 'load'], true, true); } AliasLoaderクラスのprependToLoaderStackクラスに下記の ような実装がある。 ココ!
  27. 27. spl_autoload_register 27 spl_autoload_registerに登録された関数は登録順に実行さ れるが、第3引数に true を渡せば先頭に登録される https://3v4l.org/tunNf
  28. 28. AliasLoader::load 28 spl_autoload_registerに登録されたAliasLoader::load関数 をみていきましょう。 public function load($alias) { if (static::$facadeNamespace && strpos($alias, static::$facadeNamespace) === 0) { $this->loadFacade($alias); return true; } if (isset($this->aliases[$alias])) { return class_alias($this->aliases[$alias], $alias); } }
  29. 29. AliasLoader::loadFacade 29 loadFacadesメソッドはensureFacadeExistsの結果を requireしている protected function loadFacade($alias) { require $this->ensureFacadeExists($alias); }
  30. 30. AliasLoader::ensureFacadeExists 30 file_put_contents??? protected function ensureFacadeExists($alias) { if (is_file($path = storage_path('framework/cache/facade-'.sha1($alias).'.php'))) return $path; } file_put_contents($path, $this->formatFacadeStub( $alias, file_get_contents(__DIR__.'/stubs/facade.stub') )); return $path; }
  31. 31. RealTime Facades 31 つまり、無理やりファイルを作り出し require してるのが RealTime Facades の仕組みです。
  32. 32. Realtime Facadesの個人的な感想 32 これいる?
  33. 33. 真面目に考えよう 33 • Facade にすることで DI する必要はなくなる • DIしたくないというシチュエーション • Facade にはモックに関する機能が数多くあり、テストが しやすいかもしれない 理由としては弱い気がする。これいる?(1分ぶり2回目
  34. 34. Higher Order Messages 34 マジックメソッドの活用と高階関数
  35. 35. HigherOrder Messages 35 コレクションで繁用するアクションを手短に実行するため に、"higher order messages”をサポートしました。 https://readouble.com/laravel/5.4/ja/collections.html Laravel 5.4 から導入されました
  36. 36. HigherOrder Messages 36 従来の使い方だとこう Route::get('/test', function (){ $collection = collect()->times(10, function(){ return new Article(); }); });
  37. 37. Route::get('/test', function (){ $collection = collect()->times(10, function(){ return new Article(); }); return $collection->map->mark(); }); 動かしたい人は 37 HigherOrder Messages だとこうなる https://laravelplayground.com/#/snippets/06faf2b1-6048-44bf-bec6-d08bb1e8de53
  38. 38. EnumeratesValues 38 Collectionのtrait。HigherOrder Messages 仕組みの大部分 を担当している。この場合だとプロパティに存在しない `map` はどのようになるのか https://laravelplayground.com/#/snippets/06faf2b1-6048-44bf-bec6-d08bb1e8de53
  39. 39. HigherOrderCollectionProxy 39 Collectionのtrait。HigherOrder Messages 仕組みの大部分 を担当している。この場合だとプロパティに存在しない `map` はどのようになるのか HigherOrderCollectionProxyがnewされる EnumeratesValues
  40. 40. HigherOrderCollectionProxy 40 __getというマジックメソッドを使い処理をおこなっている。 Laravelを読んだことのある人はおなじみのアレである。 高階関数的なアプローチ EnumeratesValues public function __get($key) { return $this->collection->{$this->method}(function ($value) use ($key) { return is_array($value) ? $value[$key] : $value->{$key}; }); }
  41. 41. 乱用されるHigherOrderほげほげ 41 • HigherOrderWhenProxy • HigherOrderCollectionProxy • HigherOrderTapProxy • tap関数の中で使われているやつ • フレームワークのソースコードを読むと高確率で遭遇す る • 読みにくい(小声
  42. 42. HigherOrder Messages の個人的な感想 42 これいる? (5分ぶり3回目) いや、ちょっとかっこいいけどさ…
  43. 43. まとめ 43 • フレームワークのソースコードを読むと学びがある • 様々な実装テクニックが散りばめられている • 時間的に取り上げなかったけど、Pipelineクラスとか面白い • これらのテクニックを安易に真似すると痛い目にあいがち • 熟考の末なら問題ない • プログラマとしてイキってるとやりがち(黒歴史)
  44. 44. まとめ 44 なんのかんの言っても フレームワークのソースコードを 読むのは楽しい! みんなも読もう!!
  45. 45. おしまい 45 明日も楽しんでください! Discordで🍺飲みながら まってます #bd-2-laravel-blackmagic にどうぞ!
  46. 46. • インフラエンジニア • https://www.wantedly.com/projects/188299 • PHPエンジニア • https://bosyu.togetter.dev/ • ReactNative/フロントエンドエンジニア • https://rn-bosyu.togetter.dev/ • 学生エンジニア(アルバイト) • https://baito-bosyu.togetter.dev/ We Are Hiring!!(再掲) 46

×