2022.05.02
STAFF BLOG
スタッフブログ
TECHNICAL
テクログ
初めに
こんにちは!福神漬けです。
今日は何とはなしにLaravelのサービスコンテナが何やってるのか追ってみたいと思います。
またこのブログは下記のQiitaの記事を120%参考にしています。
とてもわかりやすいのでこのブログを読んだらこちらも読んだ方がいいです。
https://qiita.com/minato-naka/items/a4531797af611688db97
サービスコンテナって?
公式はこちら
https://readouble.com/laravel/8.x/ja/container.html
ざっくり書くと、
・コンストラクタの引数でクラス名をタイプヒンティングするとそのインスタンスを渡してくれる。
・インスタンス化されるクラスも必要なクラスがあればインスタンスを渡される。
これによってどういうメリットがあるなどは余白が足らなくなるのでまた今度。
Reflectionって?
phpの公式はこちら
https://www.php.net/manual/ja/class.reflectionclass.php
サービスコンテナの処理にReflectionが使われています。
ざっくり書くと
・クラスの様々な情報を吸い取れる。
・吸い取った情報で新しくインスタンスを作れる(privateな値の書き換えもできる)
と、こんな感じなので通常のアプリケーション部分のコードでは書かないと思います。
アクセス修飾子とかめちゃめちゃにできるので。
これを使ってクラスのコンストラクタの引数などの情報を取ってこれるわけです。
実際に追ってみる
これだけだと参考先の丸パクリで終わっちゃうので、ちゃんとコード追ったよって足跡を残します。
行数なども記載しますがバージョンによって変わると思います。
自分が確認したのはバージョン6.20.44です。
①public/index.phpの38行、52行
まずはフレームワークの入口のここからですね。
38行で定石通りのrequireをしていますが、52行でわかるとおりインスタンスが返ってきてますね。
というわけで最初のrequireの中身を見にいきます。
②bootstrap/app.phpの14行
Illuminate\Foundation\Applicationをインスタンス化しています。
その後色々やってますが大筋はこのインスタンスを返すことのようです。
public/index.phpでこのインスタンスのmake()というメソッドを呼んでいるので見にいきます。
③vendor/laravel/framework/src/Illuminate/Foundation/Application.phpの767行
venderのこのあたりにlaravelのクラスがあります。
make()のコメントに「Resolve the given type from the container.」とあります。
良さそうですね。中で呼ばれている親のmake()を見に行きます。
④vendor/laravel/framework/src/Illuminate/Container/Container.phpの627行、658行
make()を見るとresolve()を呼んでいます。
書き方的に継承先のIlluminate\Foundation\Applicationのresolve()が呼ばれます。
loadDeferredProviderIfNeeded()とやらをやってますが、
処理先のコメントを読む感じプロバイダー関係のキャッシュ?っぽい感じなので今回はスルーです。
その後親のresolve()を呼んでいるので親の658行を見ます。
⑤vendor/laravel/framework/src/Illuminate/Container/Container.phpの658行、793行
さてresolveあたりから急に色々書かれ始めてとても読みにくいですが、
コメントを読んだりしていくとインスタンスのキャッシュ化だったりが読み取れると思います。
ちょっとずるい手を使いますが、すでにReflectionを使うであろうことを知っているのでファイル内で検索します。
すると793行のbuild()でReflectionClassのインスタンスが作られていることがわかります。
この辺でデバッグ処理を入れてみるとmake()やbuild()にクラス名が渡されていて、
依存関係を解決するために再起的に呼ばれていることがわかります。
補足
最初に紹介したこちらの記事ではこのブログで行った説明はもちろん、
実際にサービスコンテナを実装してみるということも書かれています。
理解を深めたい方はぜひどうぞ。
https://qiita.com/minato-naka/items/a4531797af611688db97
終わりに
正直コード追っただけの中身の薄さについては許してほしい…
ブログのネタが思いつかなくて…
とはいえ名前だけ知ってたReflectionがどういうものなのか理解が深まってよかったです。
あとフレームワークのコードを読むのは勉強になるしなんか自信つくのでおすすめです。
お疲れ様でした!