ThinkPHP6 アプリケーションの初期化 (ソースコード分析)

藏色散人
リリース: 2020-01-30 19:29:36
転載
3943 人が閲覧しました

ThinkPHP6 アプリケーションの初期化 (ソースコード分析)

#ThinkPHP6 ソース コード分析アプリケーションの初期化

App Construct

まず、__construct で何が行われるかを見てみましょう。基本的に、どのフレームワークもここでいくつかの基本的な操作を実行します。つまり、ここから拡張されます。

public function __construct(string $rootPath = '')
{
    $this->thinkPath   = dirname(__DIR__) . DIRECTORY_SEPARATOR;
    $this->rootPath    = $rootPath ? rtrim($rootPath, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR : $this->getDefaultRootPath();
    $this->appPath     = $this->rootPath . 'app' . DIRECTORY_SEPARATOR;
    $this->runtimePath = $this->rootPath . 'runtime' . DIRECTORY_SEPARATOR;
    if (is_file($this->appPath . 'provider.php')) {
        $this->bind(include $this->appPath . 'provider.php');
    }
    static::setInstance($this);
    $this->instance('app', $this);
    $this->instance('think\Container', $this);
}
ログイン後にコピー

# Magic メソッドのパラメータ rootPath から判断すると、ルート ディレクトリ パスのカスタマイズをサポートしています。

##● ThinkPath、rootPath、appPath、runtimePath が設定されます

#● デフォルトのサービス プロバイダーがバインドされており、app\Reques と app\ExceptionHandle の合計 2 つが提供されます。あなたが使用するのはリクエストです。具体的には、appPath に移動して表示します。

● 現在のコンテナ インスタンスを設定します。APP

● App($this) インスタンスをコンテナ、それぞれ app と think\Container

にバインドします。 App クラスは Container を継承するため、独自のインスタンスをコンテナにバインドすることに注意してください。

ここでアプリケーション全体が初期化されたようですね?ここでは、Request run の内容の一部をここに置く必要がありますが、これはフレームワークの主な初期化作業であるためですが、初期化作業のこの部分を Request run に置くのは合理的ではないと思います。

#Main 初期化

public function initialize()
{
    $this->initialized = true;
    $this->beginTime = microtime(true);
    $this->beginMem  = memory_get_usage();
    // 加载环境变量
    if (is_file($this->rootPath . '.env')) {
        $this->env->load($this->rootPath . '.env');
    }
    $this->configExt = $this->env->get('config_ext', '.php');
    $this->debugModeInit();
    // 加载全局初始化文件
    $this->load();
    // 加载框架默认语言包
    $langSet = $this->lang->defaultLangSet();
    $this->lang->load($this->thinkPath . 'lang' . DIRECTORY_SEPARATOR . $langSet . '.php');
    // 加载应用默认语言包
    $this->loadLangPack($langSet);
    // 监听AppInit
    $this->event->trigger('AppInit');
    date_default_timezone_set($this->config->get('app.default_timezone', 'Asia/Shanghai'));
    // 初始化
    foreach ($this->initializers as $initializer) {
        $this->make($initializer)->init($this);
    }
    return $this;
}
ログイン後にコピー

# .env 環境変数ファイルをロードします

# 設定ファイルと環境変数ファイルをロードします。アプリケーション

##● common.php をアプリケーションにロードします。

#● ヘルパー関数を thinkPath ディレクトリの helper.php にロードします。

● 構成ファイルをロードします。

● アプリケーション ディレクトリにevent.php イベントをロードします。

#● アプリケーション ディレクトリに service.php サービスを登録します。

#● 言語パックをロードします。

#● AppInit をリッスンします。イベントを実行するには、このイベントを使用してリクエスト前の作業を行うことができます

##● タイム ゾーンの設定

##● すべてのサービスを挿入してサービスを開始する

##サービス登録

#初期化プロセス中にサービス登録を実行します。サービス登録は何を行うのでしょうか?サービスの利用方法は?

public function register($service, bool $force = false)
{
    $registered = $this->getService($service);
    if ($registered && !$force) {
        return $registered;
    }
    if (is_string($service)) {
        $service = new $service($this);
    }
    if (method_exists($service, 'register')) {
        $service->register();
    }
    if (property_exists($service, 'bind')) {
        $this->bind($service->bind);
    }
    $this->services[] = $service;
}
ログイン後にコピー

# サービスが登録されているかどうか (再登録を強制する必要がある場合)

#● サービスをインスタンス化する

# register メソッドの場合実装されている場合は、それを実行する必要があります register メソッド

#バインド属性が設定されている場合、サービス インスタンスをコンテナにバインドする必要があります##最後にサービス配列全体にマージして待機しますfor boot

サービス起動

現在、初期化中のサービスは次の 3 つだけです。

##これら 3 つのサービスは次のとおりです:

foreach ($this->initializers as $initializer) {
        $this->make($initializer)->init($this);
}
ログイン後にコピー

# エラー サービスはフレームワークの例外とエラーを処理するために使用されます

##● RegisterService は文字通りサービスを登録することを意味します

#● BootService はサービスを有効にするには

エラー処理については後で説明しますが、ここでは RegisterService と BootService について説明しましょう。

RegisterServiceをContainerから作る場合

隠れた静的メソッドmakeがあり、初めてContainerからインスタンスオブジェクトを作るたびにmakeメソッドが実行されます。まずメソッドを実装する必要があります。 Init メソッドが実行されます。 RegisterService を入力すると、このメソッドが表示されます。メソッドの内容は次のとおりです。

think\initializer\BootService
think\initializer\Error
think\initializer\RegisterService
ログイン後にコピー

このメソッドは非常に奇妙で、私が想像していたものとは少し異なります。サービスは、config ディレクトリの service.php からではなく、ランタイム ディレクトリから直接取得されます。なぜそうなるのでしょうか? Composer の開発により、TP フレームワークはパッケージの自動検出も提供できます。これは、開発チームが常にコミュニティに近づくことを証明しています。これがどのように実現されるかを見てみましょう。

これはすべてコンポーザーによるものなので、rootPath の下にあるcomposer.json を見てください。一番下に行くと、次の設定が見つかります。

public function init(App $app)
{
    $file = $app->getRootPath() . 'runtime' . DIRECTORY_SEPARATOR . 'services.php';
    $services = $this->services;
    if (is_file($file)) {
        $services = array_merge($services, include $file);
    }
    foreach ($services as $service) {
        if (class_exists($service)) {
            $app->register($service);
        }
    }
}
ログイン後にコピー

From構成の観点から見ると、フレームワークは、service:discover と Vendor:publish という合計 2 つの命令を提供します。ここでは具体的な実装については説明しませんが、パッケージ検出が service:discover によって実装されることだけを知っておく必要があります。

また、ここではデフォルトで 3 つのサービスが挿入されます。

"scripts": {
    "post-autoload-dump": [
        "@php think service:discover",
        "@php think vendor:publish"
    ]
}
ログイン後にコピー

最後に BootService を見てみましょう。これは非常に簡単です。名前付けの観点から、以下がサービスを通常に開始するコードであることはわかりますが、ここで説明する必要があるのは、サービスを開始する前にサービス クラスにブート メソッドを実装する必要があるということです。

PaginatorService::class,
ValidateService::class,
ModelService::class,
ログイン後にコピー

ThinkPHP の関連知識については、

ThinkPHP チュートリアル

をご覧ください。

以上がThinkPHP6 アプリケーションの初期化 (ソースコード分析)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:cnblogs.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート