Laravelの拡張自動登録メカニズムの解読(Package Auto-discovery)

5828 ワード

記事は専門のLaravel開発者コミュニティから転送され、元のリンク:https://learnku.com/laravel/t...

Laravelパッケージの提供者と顔がどのように自動的に発見されるかを探究する前に、PHPのパッケージの概念を簡単に分析してみましょう.
1つのパッケージは、複数のプロジェクト内で多重化可能なコードフラグメントです.例えば、パッケージspatie/laravel-analyticsは、laravelプロジェクト内でGoogle統計(Google Analytics)から簡単な方法でデータを取り戻すことができます.このパッケージはGitHubに管理され、Spatieによってメンテナンスされ、それらはリリースされ続け、パッケージのバグを更新し、修復します.プロジェクトでこのパッケージを使用している場合は、いったんリリースされた更新と修復を取得したい場合は、Composerを使用してGithubから新しいコードをコピーする心配はありません.
ComposerはPHP依存管理ツールです.これにより、プロジェクトライブラリの依存関係を宣言し、管理(インストール/更新)することができます.--詳細は公式サイトgetcomposer.org
Laravelはcomposer.jsonファイルを持参し、ファイル内のrequireまたはrequire-devエントリの下に、アプリケーション機能を拡張するために必要なパッケージを提供し、composer updateを実行します.
{
    "require": {
        "spatie/laravel-analytics": "3.*",
    },
}

次のコマンドを使用して、同じ効果を達成することもできます.
composer require spatie/laravel-analytics

Composerの仕事は、必要なバージョンのパッケージを引き出し、vendorディレクトリにダウンロードすることです.上記のコマンドの実行が完了すると、パッケージ内のすべてのクラスとファイルがプロジェクトにロードされ、すぐに使用できます.composer updateを再実行するたびに、Composerはパッケージを再取得します(通常composer倉庫から引き出します).そして、あなたのプロジェクトvendorディレクトリの下にあるファイルを自動的に更新します.
LaravelプロジェクトでいくつかのLaravelパッケージを使用するには、以下の追加の手順が必要です.
  • 登録サービスプロバイダ
  • 登録エイリアス/ファセット
  • 公開リソース
  • Spatieパッケージのインストールの説明を見たことがある場合は、次のステップに進む前に、プロジェクト構成はサービスプロバイダと顔を登録する必要があります.このステップはTaylor Otwellによって定義されています.必要でない条件です.Dries Vints、いつでも新しいパッケージを導入するか、パッケージを削除することを決定します.サービスプロバイダと顔は自動的に発見されます.
    Taylorの新しい特性はメディアに宣言された.
    サービスプロバイダと顔とは?
    サービスプロバイダは、Laravelのサービスコンテナに物事をバインドし、ビュー、構成、ローカライズファイルなどのパッケージリソースをロードする場所をLaravelに通知します.--  laravel.comドキュメント
    サービスプロバイダに関する詳細な公式ドキュメントを読むことができます.
    アプリケーション・サービス・コンテナで使用可能なクラスに「static」インタフェース--laravel.comドキュメント
    さらに、顔に関する公式ドキュメントを読むことができます.
    異なる拡張パッケージを検索およびインストール/更新すると、Composerは、購読可能な複数のイベントをトリガーし、独自のコードまたはコマンドライン実行可能ファイルを実行します.興味深いイベントはpost-autoload-dumpと呼ばれます.プロジェクトに自動的にロードされた最終クラスのリストをcomposerで生成した後、Laravelはすべてのクラスにアクセスでき、アプリケーションはロードされたすべてのパッケージクラスを使用する準備ができています.
    Laravelはメインcomposerにあります.jsonファイルでこのイベントを購読します.
    "scripts": {
        "post-autoload-dump": [
            "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
            "@php artisan package:discover"
        ]
    }

    まず、postAutoloadDump()静的メソッドを呼び出します.このメソッドは、キャッシュされたサービスまたは以前に発見されたパケットをクリーンアップします.もう1つは、package:discover artisanコマンドを実行します.これは、Laravelが秘密であることを自動的に発見できることです.
    パッケージの自動検出Illuminate\Foundation\Console\PackageDiscoverCommandは、Laravelがインストールされたパッケージを発見した場所であるIlluminate\Foundation\PackageManifestメソッドをbuild()クラスで呼び出す.PackageManifestは、Laravelアプリケーションの新しいインスタンスを作成した後に直接実行されるIlluminate\Foundation\Application::registerBaseServiceProviders()から、アプリケーション・ブートの初期のコンテナに登録されています.build()メソッドでは、Laravelはvendor/composer/installed.jsonファイルを検索し、composerによって生成され、composerによってインストールされたすべての拡張パケットを含むcomposer.jsonファイルの内容を保存し、Laravelはファイルの内容をマッピングし、extra.laravelの部分を含むパケットを検索する.
    "extra": {
        "laravel": {
            "providers": [
                "Barryvdh\\Debugbar\\ServiceProvider"
            ],
            "aliases": {
                "Debugbar": "Barryvdh\\Debugbar\\Facade"
            }
        }
    }

    まず、このセクションの内容を収集し、メインcomposer.jsonファイルのextra.laravel.dont-discoverの内容を表示して、一部のパッケージまたはすべてのパッケージを自動的に発見しないかどうかを確認します.
    "extra": {
        "laravel": {
            "dont-discover": [
                "barryvdh/laravel-debugbar"
            ]
        }
    }

    配列に*を追加してlaravelが自動登録を完全に停止することを示すことができます.
    Laravelは拡張パッケージに関する情報を収集しました
    はい、必要な情報が得られると、bootstrap/cache/packages.phpにPHPファイルが作成されます.
    
      array (
        'providers' =>
        array (
          0 => 'Barryvdh\\Debugbar\\ServiceProvider',
        ),
        'aliases' =>
        array (
          'Debugbar' => 'Barryvdh\\Debugbar\\Facade',
        ),
      ),
    );

    パッケージ登録
    Laravelには2つのbootstrappersがあり、HTTPまたはコンソールカーネルの起動時に使用されます.
  • \Illuminate\Foundation\Bootstrap\RegisterFacades
  • \Illuminate\Foundation\Bootstrap\RegisterProviders

  • 最初にIlluminate\Foundation\AliasLoaderを使用してすべてのフェースをアプリケーションにロードし、Laravelはpackages.phpで生成されたファイルを表示し、Laravelが自動的に登録することを望むパッケージ内のすべての別名を抽出し、これらの別名を登録します.PackageManifest::aliases()メソッドを使用して、これらの情報を収集します.
    //   RegisterFacades::bootstrap()
    
    AliasLoader::getInstance(array_merge(
        $app->make('config')->get('app.aliases', []),
        $app->make(PackageManifest::class)->aliases()
    ))->register();

    ご覧のように、config/app.phpファイルからロードされたエイリアスは、PackageManifestクラスからロードされたエイリアスとマージされます.
    同様に、Laravelは起動時にサービスプロバイダを登録し、RegisterProviders bootstrapperはFoundation\ApplicationregisterConfiguredProviders()メソッドを呼び出し、Laravelは自動的に登録すべきすべてのパケットプロバイダを収集して登録する.
    $providers = Collection::make($this->config['app.providers'])
                    ->partition(function ($provider) {
                        return Str::startsWith($provider, 'Illuminate\\');
                    });
    
    $providers->splice(1, 0, [$this->make(PackageManifest::class)->providers()]);

    ここでは、Illuminateサービスプロバイダと、あなたのプロファイル内の他のサービスプロバイダとの間に、自動的に検出されるサービスプロバイダを注入します.これにより、プロファイルに再登録することで、拡張パッケージサービスプロバイダを上書きでき、Illuminateコンポーネントが他のサービスプロバイダをロードしようとする前にロードされることを確認します.