ご存知のように、PHP フレームワークは無数にあり、近年、その優雅さで知られるフレームワークが国内の PHPer の間で徐々に知られ、使用され始めています。しかし、Larave にはドキュメントの内容が悲惨であるという明らかな欠点があります。この記事では主に、ソースコードを通じて Laravel の依存関係注入を解析する方法に関する関連情報を紹介します。この記事は、あらゆる人の学習や作業に役立つことを願っています。
Laravel のコントローラーのコンストラクターまたはメンバー メソッドでは、次のような型制約を通じて依存関係注入を使用できます。
public function store(Request $request) { //TODO }
ここでの $request パラメーターは型制約を使用します。Request はクラス: IlluminateHttpRequest です。これは、パラメーターが次のクラスである必要があることを意味します。このクラスまたはサブクラス。
この記事では、Laravel のソースコードを分析して、メソッドでインスタンスを渡さずに Request を直接使用できる理由を確認します。フレームワークが自動的にインスタンスを作成し、パラメータを渡してくれるだけです。
1. ルート定義
ルート定義ファイルで次のようなルートが定義されます:
Route::resource('/role', 'Admin\RoleController');
これは、Laravel が追加、削除、変更、クエリ用のルート エントリを自動的に生成します。 。
この記事の冒頭のストアメソッドはコントローラーメソッドです。ルートに定義されたアクションは次の図で確認できます: AppHttpControllersAdminRoleController@store
ルートメソッド分析
に従ってコントローラーとメソッドを見つけます。ルート定義を行い、ディスパッチメソッドに実装されている特定のメソッドを実行します。
(ファイル:vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php)
public function dispatch(Route $route, $controller, $method) { $parameters = $this->resolveClassMethodDependencies( $route->parametersWithoutNulls(), $controller, $method ); if (method_exists($controller, 'callAction')) { return $controller->callAction($method, $parameters); } return $controller->{$method}(...array_values($parameters)); }
最初のresolveClassMethodDependencyメソッドは、「名前が示すように」クラスのメソッドパラメータに従って依存オブジェクトを取得することです。次に、クラスメソッドを呼び出し、オブジェクトのパラメータインジェクションを配置します。
複数の依存オブジェクトがある場合、それらは foreach によって順番に解析され、パラメーターとして挿入されます。
依存オブジェクトの例のコードを取得します:
protected function resolveClassMethodDependencies(array $parameters, $instance, $method) { if (! method_exists($instance, $method)) { return $parameters; } return $this->resolveMethodDependencies( $parameters, new ReflectionMethod($instance, $method) ); }
ここでの重要な点は、クラスのメソッド パラメータ リストを取得し、パラメータの型制約を知ることができる RelectionMethod メソッドの使用に注意してください。名前など
ここでの$instanceパラメータはRoleControllerコントローラクラス、$methodパラメータはメソッド名storeです
2.依存オブジェクトの取得例
依存オブジェクトの制約タイプをパラメータから取得した後メソッドを使用すると、この依存オブジェクトをインスタンス化できます。
protected function transformDependency(ReflectionParameter $parameter, $parameters) { $class = $parameter->getClass(); // If the parameter has a type-hinted class, we will check to see if it is already in // the list of parameters. If it is we will just skip it as it is probably a model // binding and we do not want to mess with those; otherwise, we resolve it here. if ($class && ! $this->alreadyInParameters($class->name, $parameters)) { return $parameter->isDefaultValueAvailable() ? $parameter->getDefaultValue() : $this->container->make($class->name); } }
クラス名に基づいてコンテナからオブジェクトを取得します。オブジェクトインスタンスをバインドするプロセスは、最初にサービスプロバイダーで定義されます。
次に、インスタンス化されたオブジェクトをstoreメソッドに渡すと、依存オブジェクトを使用できるようになります。
3. PHPリフレクションについて
ReflectionMethodの使用例を示します。
class Demo { private $request; public function store(Request $request) { } }
図に示すように、新しい ReflectionMethod(Demo::class, 'store') の内容を出力します。
このメソッドのパラメーター リストとパラメーターの制約タイプを取得できます。 typeHint、IlluminateHttpRequest.
クラスによると、最初にサービスプロバイダーを通じてインスタンスをバインドすることで、名前をコンテナーから取得できます。
関連する推奨事項:
Lumen フレームワークのカスタム依存関係注入に関する簡単な説明
リフレクション機構に基づいた PHP の自動依存関係注入を実現する方法の詳細な説明_php スキル
以上がLaravel の依存関係注入の解析例の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。