目次
runWithRequest () メソッド
$this->env->load($this->rootPath . '.env');
動作原理の詳細については、コメントを参照してください。
、「load」メソッドは次のように実装されます:
Theseコード行はその他の操作を実行します。コードに含まれるクラスを個別にインスタンス化し、その「init」メソッドを呼び出します。
ホームページ PHPフレームワーク ThinkPHP ThinkPHP6 アプリケーションの初期化を解析しています

ThinkPHP6 アプリケーションの初期化を解析しています

Jul 13, 2021 pm 01:51 PM
php thinkphp6

runWithRequest () メソッド

Http クラスの run() メソッドでは、 think\\Request クラスのインスタンスを取得した後、プログラムは $response = $this->runWithRequest(request); を実行します。このうち、runWithRequest() メソッドの最初の数行は次のとおりです。

protected function runWithRequest(Request $request)
{
    $this->initialize();

    // 加载全局中间件
    $this->loadMiddleware();
    .
    .
    .
ログイン後にコピー

このメソッドの最初の行は、$this->initialize();# を実行します。 ## アプリケーションを初期化するため、この初期化操作を詳しく分析してみましょう。
Http クラスの initialize() メソッド:

protected function initialize()
{
    //如果还未初始化,则初始化之
    if (!$this->app->initialized()) {
        $this->app->initialize();
    }
}
ログイン後にコピー
は、実際には

App## の initialize()# を呼び出します。 # クラス ## メソッド。このメソッドのコード:

public function initialize()
{
    // 设置应用状态为已经初始化
    $this->initialized = true;

    //记录开始时间
    $this->beginTime = microtime(true);
    //记录起始内存使用量
    $this->beginMem  = memory_get_usage();

    // ==( A )== 加载环境变量
    // $this->env跟前面的(new App())->http和$this->config都是同样的套路
    if (is_file($this->rootPath . '.env')) {
        $this->env->load($this->rootPath . '.env');
    }
    //设置配置文件后缀
    $this->configExt = $this->env->get('config_ext', '.php');
    // ==( B )== 设置调试模式
    $this->debugModeInit();

    // ==( C )== 加载应用文件和配置等操作
    $this->load();

    // 加载框架默认语言包
    $langSet = $this->lang->defaultLangSet();
    // 框架目录下对应的语言包
    // 比如:D:\dev\tp6\vendor\topthink\framework\src\lang\zh-cn.php
    $this->lang->load($this->thinkPath . 'lang' . DIRECTORY_SEPARATOR . $langSet . '.php');

    // 加载应用默认语言包
    // 这个会扫描「app/lang」里面,对应语言包文件夹的所有「.php」文件
    // 比如,app/lang/zh-cn/* 下的所有文件
    // 然后加载解析
    $this->loadLangPack($langSet);

    // 监听AppInit
    $this->event->trigger('AppInit');

    // 设置时区
    date_default_timezone_set($this->config->get('app.default_timezone', 'Asia/Shanghai'));

    // ==( D )== 初始化
    // 初始化错误和异常处理、注册系统服务和初始化系统服务
    foreach ($this->initializers as $initializer) {
        $this->make($initializer)->init($this);
    }

    return $this;
}
ログイン後にコピー
アプリケーションの初期化では多くの操作が行われます。主な操作は、環境変数の読み込み、構成ファイルの読み込み、言語パックの読み込み、AppInit の監視、および初期化子の配列。 (A) 環境変数の読み込み

対応するステートメント:

$this->env->load($this->rootPath . '.env');

このうち、

$this->env、原理は前の (new App())->http (最初の記事を参照) と同じです。クラス \think\Env のインスタンスを取得できます。 Env クラス インスタンスを取得した後、load() メソッドを呼び出します。渡されるパラメータは .env ファイルのアドレスです。 load() メソッドは次のように実装されます。

public function load(string $file): void
{
    $env = parse_ini_file($file, true) ?: [];
    $this->set($env);
}
ログイン後にコピー
このメソッドは、.env ファイルの値を読み取った後、

set() を呼び出します。 メソッドから構成は、Env クラスの $data メンバー変数に保存されます。 set() メソッド コード:

public function set($env, $value = null): void
{
    if (is_array($env)) {
        //全部KEY转为大写字母
        $env = array_change_key_case($env, CASE_UPPER);

        foreach ($env as $key => $val) {
            //有二级配置的,转为KEY1_KEY2 => $v 的形式
            if (is_array($val)) {
                foreach ($val as $k => $v) {
                    $this->data[$key . '_' . strtoupper($k)] = $v;
                }
            } else {
                $this->data[$key] = $val;
            }
        }
        //ENV的值不是数组的情况
    } else {
        $name = strtoupper(str_replace('.', '_', $env));

        $this->data[$name] = $value;
    }
}
ログイン後にコピー
.env から読み取られる値はおそらく次のようになります:


ThinkPHP6 アプリケーションの初期化を解析しています$this->set($env)

その後、おそらく次のようになります:

#(B) デバッグ モードの設定

ThinkPHP6 アプリケーションの初期化を解析しています

$this->debugModeInit()

動作原理の詳細については、コメントを参照してください。

protected function debugModeInit(): void
{
    // 应用调试模式
    if (!$this->appDebug) {
        $this->appDebug = $this->env->get('app_debug') ? true : false;
        // 关闭错误显示
        ini_set('display_errors', 'Off');
    }
    // 如果不是命令行模式
    if (!$this->runningInConsole()) {
        // 重新申请一块比较大的buffer
        // php缓冲控制
        // 参考:https://www.php.net/manual/en/ref.outcontrol.php
        // https://www.cnblogs.com/saw2012/archive/2013/01/30/2882451.html
        // 新版PHP默认开启缓冲区ob_start(),ob_get_level() == 1
        if (ob_get_level() > 0) {
            // 相当于ob_get_contents() 和 ob_clean()
            // 获取缓冲区内容并删除缓冲区内容
            $output = ob_get_clean();
        }
        // 开启新的缓冲区控制
        ob_start();
        if (!empty($output)) {
            // 由于开启了新的缓冲区控制,
            // 这里不会直接输出$output
            // 而是等到依次执行了ob_flush()和flash()之后才将内容输出到浏览器
            echo $output;
        }
    }
}
ログイン後にコピー

ここにはバグがあるようです。$this->appDebug = $this->env->get('app\_debug') を実行する必要があります。 ? true : false; デバッグ モードの構成を取得し、次に判断します:

if(!$this->appDebug)

(C) アプリケーション ファイルと構成操作のロード次に実行

$this->load();

、「load」メソッドは次のように実装されます:

protected function load(): void
{
    $appPath = $this->getAppPath();

    // 加载「app」目录下的「common.php」文件
    if (is_file($appPath . 'common.php')) {
        include_once $appPath . 'common.php';
    }
    // 加载核心目录下的「helper.php」文件
    // 可以看到,这里的加载顺序:先「common.php」,后「helper.php」
    // 且「helper.php」中的函数包裹在「if (!function_exists('xxx'))」下
    // 所以可以在「common.php」文件中覆盖系统定义的助手函数
    include_once $this->thinkPath . 'helper.php';

    $configPath = $this->getConfigPath();

    $files = [];

    // glob的作用是扫描给定路径模式下的文件,非常好用
    // 这里扫描「config」目录下的所有「.php」文件
    if (is_dir($configPath)) {
        $files = glob($configPath . '*' . $this->configExt);
    }

    foreach ($files as $file) {
        // $this->config 还是同样的套路获得了「Config」类的实例
        // 「load」的第二个参数为一级配置名,这里传入一个文件名,所有文件名作为一级配置
        // 比如「app.php」配置文件,一级配置为「app」
        // 在 「Config」类作用域下的操作:
        // 「load」加载文件后,通过「parse」方法解析文件内容
        // 最后,通过「set」方法将所有配置合并了「config」成员变量
        $this->config->load($file, pathinfo($file, PATHINFO_FILENAME));
    }

    // 加载「app」目录下的「event.php」文件
    if (is_file($appPath . 'event.php')) {
        $this->loadEvent(include $appPath . 'event.php');
    }
    // 注册自定义的服务
    if (is_file($appPath . 'service.php')) {
        $services = include $appPath . 'service.php';
        foreach ($services as $service) {
            $this->register($service);
        }
    }
}
ログイン後にコピー

プログラムは最初に「common.php」をロードし、次に「helper.php」をロードし、「helper.php」内の関数は「if (!function_exists ('xxx')」でラップされていることに注意してください。 )」なので、必要に応じて、「common.php」ファイル内のシステム定義のヘルパー関数をオーバーライドできます。 これら 2 つのファイルをロードすることに加えて、このメソッドは「config」ディレクトリ内のすべての構成ファイルもスキャンし、それらを

Config

クラスの

$config

にロードします。メンバー変数は、「app」ディレクトリ内の「event.php」ファイルを読み込み、カスタム サービスを読み込み、登録します。 (D) 初期化エラーと例外処理、システム サービスの登録とシステム サービスの初期化次に、初期化関数の最後の段落を見てください:

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

Theseコード行はその他の操作を実行します。コードに含まれるクラスを個別にインスタンス化し、その「init」メソッドを呼び出します。

initializers

配列の値は次のとおりです。

protected $initializers = [
    Error::class,  //错误处理类
    RegisterService::class, //注册系统服务类
    BootService::class,  //启动系统服务
];
ログイン後にコピー

システム エラー処理クラスをスキップして、最初に登録システム サービス クラスを確認します。このクラスにはメンバー変数があることに注意してください。<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">protected $services = [     PaginatorService::class,     ValidateService::class,     ModelService::class, ];</pre><div class="contentsignin">ログイン後にコピー</div></div> には 3 つのコア システム サービスが含まれています。

init

メソッドでは、これらのサービスはシステム サービスに登録され、前のカスタム サービスとマージされます。その主な実装コードは次のとおりです:

foreach ($services as $service) {
    if (class_exists($service)) {
        // 注册到系统服务
        $app->register($service);
    }
}
ログイン後にコピー

最後のインスタンス化は、システム サービス クラスを開始することです、このクラスの init メソッドは、

App

クラスの boot メソッドのみを呼び出します。このメソッドの機能は、各システム サービスを初期化することです。各サービスの boot メソッドを呼び出します。 スタートアップ システム サービス クラスは次のように実装されます:

class BootService
{
    public function init(App $app)
    {
        $app->boot();
    }
}
ログイン後にコピー
App
クラスの boot

メソッド: <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">public function boot(): void {     array_walk($this-&gt;services, function ($service) {         $this-&gt;bootService($service);     }); }</pre><div class="contentsignin">ログイン後にコピー</div></div>キーは bootService メソッド:

public function bootService($service)
{
    if (method_exists($service, 'boot')) {
        return $this->invoke([$service, 'boot']);
    }
}
ログイン後にコピー

このメソッドは、各サービスの boot メソッドを個別に呼び出して、登録されたサービスを初期化します。

上記のコードからわかるように、システムによって登録されたサービスのソースが 3 つあります。

システムには、
PaginatorService

、## などのシステムが付属しています。 #ValidateService
    ,
  1. ModelService; これは、アプリ ディレクトリの "service.php" ファイルでカスタマイズされ、 ベンダー ディレクトリ。
  2. 初期化後、「App」クラスのインスタンスはおそらく次のようになります:
  3. ThinkPHP6 アプリケーションの初期化を解析しています

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

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

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

PHPとPython:2つの一般的なプログラミング言語を比較します PHPとPython:2つの一般的なプログラミング言語を比較します Apr 14, 2025 am 12:13 AM

PHPとPythonにはそれぞれ独自の利点があり、プロジェクトの要件に従って選択します。 1.PHPは、特にWebサイトの迅速な開発とメンテナンスに適しています。 2。Pythonは、データサイエンス、機械学習、人工知能に適しており、簡潔な構文を備えており、初心者に適しています。

アクション中のPHP:実際の例とアプリケーション アクション中のPHP:実際の例とアプリケーション Apr 14, 2025 am 12:19 AM

PHPは、電子商取引、コンテンツ管理システム、API開発で広く使用されています。 1)eコマース:ショッピングカート機能と支払い処理に使用。 2)コンテンツ管理システム:動的コンテンツの生成とユーザー管理に使用されます。 3)API開発:RESTFUL API開発とAPIセキュリティに使用されます。パフォーマンスの最適化とベストプラクティスを通じて、PHPアプリケーションの効率と保守性が向上します。

PHP:Web開発の重要な言語 PHP:Web開発の重要な言語 Apr 13, 2025 am 12:08 AM

PHPは、サーバー側で広く使用されているスクリプト言語で、特にWeb開発に適しています。 1.PHPは、HTMLを埋め込み、HTTP要求と応答を処理し、さまざまなデータベースをサポートできます。 2.PHPは、ダイナミックWebコンテンツ、プロセスフォームデータ、アクセスデータベースなどを生成するために使用され、強力なコミュニティサポートとオープンソースリソースを備えています。 3。PHPは解釈された言語であり、実行プロセスには語彙分析、文法分析、編集、実行が含まれます。 4.PHPは、ユーザー登録システムなどの高度なアプリケーションについてMySQLと組み合わせることができます。 5。PHPをデバッグするときは、error_reporting()やvar_dump()などの関数を使用できます。 6. PHPコードを最適化して、キャッシュメカニズムを使用し、データベースクエリを最適化し、組み込み関数を使用します。 7

PHPの永続的な関連性:それはまだ生きていますか? PHPの永続的な関連性:それはまだ生きていますか? Apr 14, 2025 am 12:12 AM

PHPは依然として動的であり、現代のプログラミングの分野で重要な位置を占めています。 1)PHPのシンプルさと強力なコミュニティサポートにより、Web開発で広く使用されています。 2)その柔軟性と安定性により、Webフォーム、データベース操作、ファイル処理の処理において顕著になります。 3)PHPは、初心者や経験豊富な開発者に適した、常に進化し、最適化しています。

PHP対Python:違いを理解します PHP対Python:違いを理解します Apr 11, 2025 am 12:15 AM

PHP and Python each have their own advantages, and the choice should be based on project requirements. 1.PHPは、シンプルな構文と高い実行効率を備えたWeb開発に適しています。 2。Pythonは、簡潔な構文とリッチライブラリを備えたデータサイエンスと機械学習に適しています。

PHPおよびPython:コードの例と比較 PHPおよびPython:コードの例と比較 Apr 15, 2025 am 12:07 AM

PHPとPythonには独自の利点と短所があり、選択はプロジェクトのニーズと個人的な好みに依存します。 1.PHPは、大規模なWebアプリケーションの迅速な開発とメンテナンスに適しています。 2。Pythonは、データサイエンスと機械学習の分野を支配しています。

PHP対その他の言語:比較 PHP対その他の言語:比較 Apr 13, 2025 am 12:19 AM

PHPは、特に迅速な開発や動的なコンテンツの処理に適していますが、データサイエンスとエンタープライズレベルのアプリケーションには良くありません。 Pythonと比較して、PHPはWeb開発においてより多くの利点がありますが、データサイエンスの分野ではPythonほど良くありません。 Javaと比較して、PHPはエンタープライズレベルのアプリケーションでより悪化しますが、Web開発により柔軟性があります。 JavaScriptと比較して、PHPはバックエンド開発により簡潔ですが、フロントエンド開発のJavaScriptほど良くありません。

PHPおよびPython:さまざまなパラダイムが説明されています PHPおよびPython:さまざまなパラダイムが説明されています Apr 18, 2025 am 12:26 AM

PHPは主に手順プログラミングですが、オブジェクト指向プログラミング(OOP)もサポートしています。 Pythonは、OOP、機能、手続き上のプログラミングなど、さまざまなパラダイムをサポートしています。 PHPはWeb開発に適しており、Pythonはデータ分析や機械学習などのさまざまなアプリケーションに適しています。

See all articles