ホームページ  >  記事  >  バックエンド開発  >  ソースコードを通じてLaravel依存関係注入関連コンテンツを解析する

ソースコードを通じてLaravel依存関係注入関連コンテンツを解析する

jacklove
jackloveオリジナル
2018-06-29 17:40:201522ブラウズ

この記事では、ソース コードを通じて Laravel の依存関係注入を解析する方法に関する関連情報を主に紹介します。この記事は、それを必要とするすべての人の学習や学習に役立つ情報を提供します。フォローできます 編集者と一緒に学びましょう。

まえがき

ご存知のとおり、PHP フレームワークは無数にあり、近年、その優雅さで知られるフレームワークが徐々に知られるようになりました。国内の PHPer が開発し、使い始めましたが、larave の明らかな欠点の 1 つは、そのドキュメントの内容が残念なことです。

この記事では、Laravel の依存関係注入について詳しく説明し、参考と学習のために共有します。以下では多くを説明しません。詳細な紹介を見てみましょう。

Laravel コントローラーのコンストラクターまたはメンバー メソッドでは、次のような型制約を通じて依存関係注入を使用できます。

public function store(Request $request)
{
 //TODO
}

ここで、 $request パラメータは型制約を使用します。リクエストは class:\Illuminate\Http\Request です。これは、パラメータがこのクラスまたはサブクラスである必要があることを意味します。

この記事では、Laravel のソース コードを分析して、メソッドでインスタンスを渡さずに Request を直接使用できる理由を確認します。フレームワークが自動的にインスタンスを作成し、パラメータを渡してくれるだけです。

#1. ルート定義

ソースから見ると、次のようなルートがルート定義ファイルに定義されています。

Route::resource('/role', 'Admin\RoleController');

これはリソースベースのルートで、Laravel は追加、削除、変更、クエリのためのルーティング エントリを自動的に生成します。

この記事の冒頭のストア メソッドは、図に表示されているルートによって定義されているアクションも App\Http\Controllers\Admin\ です。 RoleController@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)
 );
}

ここで重要な点は、PHP リフレクションの使用に注意してください。クラスメソッドのパラメータリストを取得することで、パラメータの型制約やパラメータ名などを知ることができます。

ここでの $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);
 }
}

クラス名に基づいてコンテナからオブジェクトを取得します。オブジェクト インスタンスをバインドするプロセスは、最初にサービス プロバイダーで定義されます。

次に、インスタンス化されたオブジェクトをストア メソッドに渡すと、依存オブジェクトを使用できるようになります。

3. PHP リフレクションについて

ReflectionMethod の使用例を示します。

#
class Demo
{
 private $request;
 public function store(Request $request)
 {
 }
}

#図に示すように、新しい ReflectionMethod(Demo::class, 'store') の内容を出力します。

#このメソッドのパラメータ リスト、パラメータの制約タイプ (typeHint、Illuminate\Http\Request など) を取得できます。

クラス名に従って、インスタンスは最初にコンテナーからサービスプロバイダーを介してバインドされます。

#概要

興味があるかもしれない記事:

php データ構造逐次リンクリストとリンク線形リストの例

PHP でのエコーでのカンマとドットの使用の違いに基づいた詳細な説明

バイナリ内の 1 の数の統計アルゴリズムを実装する PHP の例


以上がソースコードを通じてLaravel依存関係注入関連コンテンツを解析するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。