ホームページ  >  記事  >  PHPフレームワーク  >  コード内でコンテナインスタンスを取得する(Laravel)

コード内でコンテナインスタンスを取得する(Laravel)

藏色散人
藏色散人転載
2021-08-06 09:35:101860ブラウズ

この記事は、laravel のチュートリアルコラムで、コード内でコンテナインスタンスを取得する方法を紹介する記事です。

laravel コンテナインスタンスはリクエストライフサイクル全体を通じて一意であり、すべてのサービスコンポーネントインスタンスを管理します。それでは、laravelコンテナのインスタンスを取得するにはどのような方法があるのでしょうか?以下の方法が一般的に使用されます:

1) アプリのヘルプ機能経由:

$app = app();

アプリの補助機能は

コード内でコンテナインスタンスを取得する(Laravel)

# で定義されています。 ## このファイルでは、多くのヘルプ関数が定義されており、composer を通じてプロジェクトに自動的にロードされます。したがって、関数には、app() などの http リクエスト処理に関係する任意のコードの場所からアクセスできます。

2) アプリ ファサード経由

<?php
Route::get(&#39;/&#39;, function () {
    dd(App::basePath());
    return &#39;&#39;;
});

アプリ ファサード経由でコンテナ インスタンスを取得する方法は上記とは異なります。最初にアプリを変数に割り当ててからコンテナを呼び出すことはできません変数を通じて。これは、App は単なるクラス名であり、クラス名を変数にコピーできないためです。 $app = App; は正当な実行可能ステートメントではありませんが、 $app = app(); の後に関数呼び出しを表す app() が続くため、正当な実行可能ステートメントとなります。 App::basePath(); も正当なステートメントであり、クラスの静的メソッドを呼び出しています。

さらに 2 つのポイントを追加します:

最初のポイント: Facade は、laravel フレームワークの特別な機能です。各 Facade は、コンテナー内のインスタンス オブジェクトに関連付けられます。Facade を直接渡すことができます。クラスの静的メソッド呼び出しは、関連付けられたインスタンス オブジェクトのメソッドを呼び出すために使用されます。たとえば、App::basePath() を呼び出すときの App のファサードは、実際には app()->basePath() と同等です。

この基礎となるメカニズムは、PHP 言語の特性にも依存します。各 Facade に静的メンバーを設定し、それをサービスのインスタンス オブジェクトに関連付ける必要があります。Facade クラスの静的メソッドを呼び出すとき、呼び出されたメソッド名を解析し、関連付けられたサービス インスタンスの同じ名前のメソッドを呼び出し、最後に結果を返します。

Facade がどのような役割を果たし得るのかを理解するだけで十分だと思います。実装の詳細を理解するために最下層を掘り下げる必要はありません。結局のところ、実際の開発では、Facade は使用されません。 laravelフレームワークの使用には全く影響しません。また、実際のコーディングでは、Facade のカスタマイズが非常に簡単で、laravel でカプセル化された Facade 基本クラスを継承するだけです:

<?php
namespace ThirdProviders\CasServer\Facades;
use Illuminate\Support\Facades\Facade;
use ThirdProviders\CasServer\CasServerManager;
class CasServer extends Facade
{
    protected static function getFacadeAccessor()
    {
        return CasServerManager::class;
    }
}

Facade 基本クラスの getFacadeAccessor メソッドを実装すると、laravel フレームワークが何を認識するかがわかります。この Facade クラスは、どのサービス インスタンスが関連付けられているかのようになる必要があります。実際、この getFacadeAccess メソッドによって返される名前は、後で紹介するサービス バインディング名です。 laravelコンテナでは、サービスインスタンスには固定のバインド名があり、この名前を通じてインスタンスを見つけることができます。では、なぜ Facade クラスはサービス バインディング名を返すだけでよいのでしょうか。

App Facade クラスのコードを見てみましょう:

<?php
namespace Illuminate\Support\Facades;
/**
 * @see \Illuminate\Foundation\Application
 */
class App extends Facade
{
    /**
     * Get the registered name of the component.
     *
     * @return string
     */
    protected static function getFacadeAccessor()
    {
        return &#39;app&#39;;
    }
}

その getFacadeAccessor は文字列「app」を返します。これは、laravel コンテナーがそれ自体をバインドするために使用する名前です。

2 番目のポイント: 前のポイントの App Facade のソース コードから、App Facade の完全なクラス名が実際には Illuminate\Support\Facades\App であることがわかります。コード内で直接使用できますか? アプリにはショート ネームでアクセスできます:

<?php
Route::get(&#39;/&#39;, function () {
    dd(App::basePath());
    return &#39;&#39;;
});

上記のコードでは、Illuminate\Support\Facades\App を使用する方法や完全修飾方法を使用していないことがわかります。実際、App は Illuminate\Support\Facades\App と完全に同等ですが、App は Illuminate\Support\Facades\App よりもはるかに短く、使用する必要がないため、使いやすい点が異なります。これは、laravel コンテナーで設定されたエイリアスに関連しています。config/app.php の

には、いくつかのタイプのエイリアスの設定に特に使用されるエイリアスのセクションがあります:

&#39;aliases&#39; => [
    &#39;App&#39; => Illuminate\Support\Facades\App::class,
    &#39;Artisan&#39; => Illuminate\Support\Facades\Artisan::class,
    &#39;Auth&#39; => Illuminate\Support\Facades\Auth::class,
    &#39;Blade&#39; => Illuminate\Support\Facades\Blade::class,
    &#39;Bus&#39; => Illuminate\Support\Facades\Bus::class,
    &#39;Cache&#39; => Illuminate\Support\Facades\Cache::class,
    &#39;Config&#39; => Illuminate\Support\Facades\Config::class,
    &#39;Cookie&#39; => Illuminate\Support\Facades\Cookie::class,
    &#39;Crypt&#39; => Illuminate\Support\Facades\Crypt::class,
    &#39;DB&#39; => Illuminate\Support\Facades\DB::class,
    &#39;Eloquent&#39; => Illuminate\Database\Eloquent\Model::class,
    &#39;Event&#39; => Illuminate\Support\Facades\Event::class,
    &#39;File&#39; => Illuminate\Support\Facades\File::class,
    &#39;Gate&#39; => Illuminate\Support\Facades\Gate::class,
    &#39;Hash&#39; => Illuminate\Support\Facades\Hash::class,
    &#39;Lang&#39; => Illuminate\Support\Facades\Lang::class,
    &#39;Log&#39; => Illuminate\Support\Facades\Log::class,
    &#39;Mail&#39; => Illuminate\Support\Facades\Mail::class,
    &#39;Notification&#39; => Illuminate\Support\Facades\Notification::class,
    &#39;Password&#39; => Illuminate\Support\Facades\Password::class,
    &#39;Queue&#39; => Illuminate\Support\Facades\Queue::class,
    &#39;Redirect&#39; => Illuminate\Support\Facades\Redirect::class,
    &#39;Redis&#39; => Illuminate\Support\Facades\Redis::class,
    &#39;Request&#39; => Illuminate\Support\Facades\Request::class,
    &#39;Response&#39; => Illuminate\Support\Facades\Response::class,
    &#39;Route&#39; => Illuminate\Support\Facades\Route::class,
    &#39;Schema&#39; => Illuminate\Support\Facades\Schema::class,
    &#39;Session&#39; => Illuminate\Support\Facades\Session::class,
    &#39;Storage&#39; => Illuminate\Support\Facades\Storage::class,
    &#39;URL&#39; => Illuminate\Support\Facades\URL::class,
    &#39;Validator&#39; => Illuminate\Support\Facades\Validator::class,
    &#39;View&#39; => Illuminate\Support\Facades\View::class
],

その後、リクエストは次のようになります。 laravelフレームワークで処理される プロセス中に、これらのエイリアスはIlluminate\Foundation\Bootstrap\RegisterFacadesクラスを通じてグローバル環境に登録されます:

<?php
namespace Illuminate\Foundation\Bootstrap;
use Illuminate\Support\Facades\Facade;
use Illuminate\Foundation\AliasLoader;
use Illuminate\Contracts\Foundation\Application;
class RegisterFacades
{
    /**
     * Bootstrap the given application.
     *
     * @param  \Illuminate\Contracts\Foundation\Application  $app
     * @return void
     */
    public function bootstrap(Application $app)
    {
        Facade::clearResolvedInstances();
        Facade::setFacadeApplication($app);
        AliasLoader::getInstance($app->make(&#39;config&#39;)->get(&#39;app.aliases&#39;, []))->register();
    }
}

したがって、完全な型名の代わりにエイリアスを直接使用して実行できます。同じアクセス機能です。長い名前のクラスを自分で作成し、コード内で頻繁に使用されている場合は、それらを config/app.php エイリアスで構成することも検討できます。そうすれば、laravel がそれらを登録します。

3) laravel コンテナインスタンスを取得するもう 1 つの方法は、サービスプロバイダーで $this->app

を直接使用することです。サービスプロバイダーについては後で紹介しますが、紹介したばかりです。今。サービスプロバイダークラスはlaravelコンテナーによってインスタンス化されるため、これらのクラスはIlluminate\Support\ServiceProviderを継承し、サービスプロバイダーのインスタンス化時にインスタンス属性$app

コード内でコンテナインスタンスを取得する(Laravel)

laravelを定義します。 、laravelコンテナインスタンスが$appに注入されます。したがって、サービスプロバイダーでは、app() 関数や App Facade を使用せずに、$this->$app を通じて常に laravel コンテナインスタンスにアクセスできます。

laravel の技術記事をさらに詳しく知りたい場合は、laravel チュートリアル 列をご覧ください。

以上がコード内でコンテナインスタンスを取得する(Laravel)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事は杨子で複製されています。侵害がある場合は、admin@php.cn までご連絡ください。