ホームページ  >  記事  >  PHPフレームワーク  >  TP5フレームワークの入力から出力インターフェースまでのロードプロセスを分析します。

TP5フレームワークの入力から出力インターフェースまでのロードプロセスを分析します。

藏色散人
藏色散人転載
2021-09-16 15:12:282812ブラウズ

thinkphp フレームワークチュートリアル コラムでは、ThinkPHP5 フレームワークの入り口から出力インターフェイスまでの読み込みプロセスを紹介および分析します。

ThinkPHP のインストール

詳しくは説明しませんインストール方法については、公式ドキュメント - ThinkPHP のインストールは非常に完了しています。Composer、Git、または ThinkPHP 公式 Web サイトから直接 zip パッケージをダウンロードできます。私がインストールしたバージョンは 5.0.24

Test run

ダウンロードとインストールが完了しました。最後に、プロジェクトのダウンロード ディレクトリがローカル サーバーのプロジェクト ルート ディレクトリにある場合は、アドレス http://localhost/thinkphp5/public/## を直接入力できます。 # 以下の図に示すように、ブラウザで ThinkPHP5 のデフォルトのようこそページに入ります。これは、ThinkPHP5 が正常にインストールされたことを意味します

上記の方法でアドレスを実行することに加えて、Apache または Nginx を通じてアドレスを実行することもできます プロジェクトにアクセスするように仮想ホストを構成します。興味がある場合は、特定のチュートリアルをオンラインで確認し、アクセス用に仮想ホストを構成できます。

では本題に入ります。ThinkPHP5 の実行プロセスを段階的に分析してみましょう...

エントリー ファイル (publicindex.php)

Open

public\ Index.phpファイルの後に、エントリ ファイルの元のコードが次のとおりであることがわかります。

// [ 应用入口文件 ]

// 定义应用目录
define('APP_PATH', __DIR__ . '/../application/');
// 加载框架引导文件
require __DIR__ . '/../thinkphp/start.php';
エントリ ファイルのコードは非常に簡潔で、わずか 2 行のコードで、関数は

  1. define(' APP_PATH', __DIR__ . '/../application/');アプリケーション ディレクトリを定義する定数 APP_PATH
  2. require __DIR__ 。 '/../thinkphp/start.php';フレームワーク ブート ファイルのロード
  3. ##上記の 2 つの関数に加えて、エントリ ファイルに独自の定数を定義することもできます。コード行を追加します。
define('PUBLIC_PATH' , __DIR__ .'/../public');

パブリック ディレクトリの定数と前処理などを定義します。フレームワークをロードします。ブート ファイル (thinkphpstart.php)

同様に、ファイルの後に

thinkphp\start.php

と入力すると、多くのコードがないことがわかります<pre class="brush:php;toolbar:false">namespace think; // ThinkPHP 引导文件 // 1. 加载基础文件 require __DIR__ . '/base.php'; // 2. 执行应用 App::run()-&gt;send();</pre>これら 2 つの短い内容からコード行を見ると、左右に 2 つのメインがあることがわかります。

    require __DIR__ . '/base.php';
  1. ベース ファイルのロード
  2. App::run()->send();
  3. アプリケーションを実行します
  4. 次の 2 つの主要なポイントで、左右の 2 人が行ったことを詳しく紹介します

基本ファイル (thinkphpbase.php) をロードします

続きましょう

thinkphp\base.php

ファイルを開くと、このファイルには以前のような 2 行のコードしか含まれていないことがわかります。 2 つのファイル...<pre class="brush:php;toolbar:false">define('THINK_VERSION', '5.0.24'); define('THINK_START_TIME', microtime(true)); define('THINK_START_MEM', memory_get_usage()); define('EXT', '.php'); define('DS', DIRECTORY_SEPARATOR); defined('THINK_PATH') or define('THINK_PATH', __DIR__ . DS); define('LIB_PATH', THINK_PATH . 'library' . DS); define('CORE_PATH', LIB_PATH . 'think' . DS); define('TRAIT_PATH', LIB_PATH . 'traits' . DS); defined('APP_PATH') or define('APP_PATH', dirname($_SERVER['SCRIPT_FILENAME']) . DS); defined('ROOT_PATH') or define('ROOT_PATH', dirname(realpath(APP_PATH)) . DS); defined('EXTEND_PATH') or define('EXTEND_PATH', ROOT_PATH . 'extend' . DS); defined('VENDOR_PATH') or define('VENDOR_PATH', ROOT_PATH . 'vendor' . DS); defined('RUNTIME_PATH') or define('RUNTIME_PATH', ROOT_PATH . 'runtime' . DS); defined('LOG_PATH') or define('LOG_PATH', RUNTIME_PATH . 'log' . DS); defined('CACHE_PATH') or define('CACHE_PATH', RUNTIME_PATH . 'cache' . DS); defined('TEMP_PATH') or define('TEMP_PATH', RUNTIME_PATH . 'temp' . DS); defined('CONF_PATH') or define('CONF_PATH', APP_PATH); // 配置文件目录 defined('CONF_EXT') or define('CONF_EXT', EXT); // 配置文件后缀 defined('ENV_PREFIX') or define('ENV_PREFIX', 'PHP_'); // 环境变量的配置前缀 // 环境常量 define('IS_CLI', PHP_SAPI == 'cli' ? true : false); define('IS_WIN', strpos(PHP_OS, 'WIN') !== false); // 载入Loader类 require CORE_PATH . 'Loader.php'; // 加载环境变量配置文件 if (is_file(ROOT_PATH . '.env')) {     $env = parse_ini_file(ROOT_PATH . '.env', true);     foreach ($env as $key =&gt; $val) {         $name = ENV_PREFIX . strtoupper($key);         if (is_array($val)) {             foreach ($val as $k =&gt; $v) {                 $item = $name . '_' . strtoupper($k);                 putenv(&quot;$item=$v&quot;);             }         } else {             putenv(&quot;$name=$val&quot;);         }     } } // 注册自动加载 \think\Loader::register(); // 注册错误和异常处理机制 \think\Error::register(); // 加载惯例配置文件 \think\Config::set(include THINK_PATH . 'convention' . EXT);</pre>よく見てみると、コードは 6 行以上ありますが、コードの機能は明らかです。主な機能は次の 6 点です

    define('', '')
  1. 関数を使用して、多くのシステム定数を定義します。さらに 2 つの環境定数を定義します。後で使用するためにローダー クラス (thinkphplibrarythinkloader.php) を導入します
  2. 環境変数設定ファイルをロードします (環境変数設定ファイルの名前は
  3. .env
  4. です。このファイルは必ずしも存在するわけではありません。実際の開発プロセス中に必要に応じて追加されます)
  5. Call
  6. \think\Loader::register()

    自動読み込みメカニズムの登録

    登録システムの自動読み込み
    • Composer
    • 自動読み込みサポート登録名前空間定義
    • クラス ライブラリ マッピング ファイルを読み込み、
    • runtime
    • キャッシュ ディレクトリに存在しますclassmap.php自動的にロード
    • extend
    • ディレクトリ
    • ##call
    \think\Error::register()
  7. 例外およびエラー処理メカニズムを登録
  8. #規約設定ファイルをロードする (thinkphpconvention.php)
  9. アプリケーションを実行する (thinkphplibrarythinkApp.php)
  10. 便宜上、この run メソッドのコードは少し長いですが、それでもメソッド全体を投稿することを選択します。私を叩かないでください。
/**
 * 执行应用程序
 * @access public
 * @param  Request $request 请求对象
 * @return Response
 * @throws Exception
 */
public static function run(Request $request = null)
{
    $request = is_null($request) ? Request::instance() : $request;

    try {
        $config = self::initCommon();

        // 模块/控制器绑定
        if (defined('BIND_MODULE')) {
            BIND_MODULE && Route::bind(BIND_MODULE);
        } elseif ($config['auto_bind_module']) {
            // 入口自动绑定
            $name = pathinfo($request->baseFile(), PATHINFO_FILENAME);
            if ($name && 'index' != $name && is_dir(APP_PATH . $name)) {
                Route::bind($name);
            }
        }

        $request->filter($config['default_filter']);

        // 默认语言
        Lang::range($config['default_lang']);
        // 开启多语言机制 检测当前语言
        $config['lang_switch_on'] && Lang::detect();
        $request->langset(Lang::range());

        // 加载系统语言包
        Lang::load([
            THINK_PATH . 'lang' . DS . $request->langset() . EXT,
            APP_PATH . 'lang' . DS . $request->langset() . EXT,
        ]);

        // 监听 app_dispatch
        Hook::listen('app_dispatch', self::$dispatch);
        // 获取应用调度信息
        $dispatch = self::$dispatch;

        // 未设置调度信息则进行 URL 路由检测
        if (empty($dispatch)) {
            $dispatch = self::routeCheck($request, $config);
        }

        // 记录当前调度信息
        $request->dispatch($dispatch);

        // 记录路由和请求信息
        if (self::$debug) {
            Log::record('[ ROUTE ] ' . var_export($dispatch, true), 'info');
            Log::record('[ HEADER ] ' . var_export($request->header(), true), 'info');
            Log::record('[ PARAM ] ' . var_export($request->param(), true), 'info');
        }

        // 监听 app_begin
        Hook::listen('app_begin', $dispatch);

        // 请求缓存检查
        $request->cache(
            $config['request_cache'],
            $config['request_cache_expire'],
            $config['request_cache_except']
        );

        $data = self::exec($dispatch, $config);
    } catch (HttpResponseException $exception) {
        $data = $exception->getResponse();
    }

    // 清空类的实例化
    Loader::clearInstance();

    // 输出数据到客户端
    if ($data instanceof Response) {
        $response = $data;
    } elseif (!is_null($data)) {
        // 默认自动识别响应输出类型
        $type = $request->isAjax() ?
        Config::get('default_ajax_return') :
        Config::get('default_return_type');

        $response = Response::create($data, $type);
    } else {
        $response = Response::create();
    }

    // 监听 app_end
    Hook::listen('app_end', $response);

    return $response;
}

これは約 90 行のコードです。正確に何が行われるのか、アノテーション分析と組み合わせて、主な機能は次のステップです

最初のステップ: 変数

$request

を処理して、変数が有効であり、null ではないことを確認します
  • 2 番目のステップ: self::initCommon()
  • 現在のコントローラーで initCommon() メソッドを呼び出します。このメソッドは、アプリケーションを初期化し、構成情報を返す役割を果たします
  • Loader::addNamespace(self::$namespace, APP_PATH) ;

    名前空間の登録
    • self::init()
    • このクラスの init () メソッドを呼び出してアプリケーションを初期化します
      • さまざまな構成ファイルのロード
      • 動作拡張ファイルのロード
      • パブリック ファイルのロード
      • 言語パックのロード
    • デバッグ モード関連の処理を適用します。
    • 追加ファイルをロードし、構成項目の値を介して関連ファイルをロードします。
    • extra_file_list
    • date_default_timezone_set($config['default_timezone'] );システムのタイムゾーンを設定します
    • 呼び出し
    • Hook::listen('app_init');app_init タグをリッスンする動作
    ##3 番目のステップ: モジュールまたはコントローラーをバインドするかどうかを決定します
  • ステップ 4: システム言語の設定と読み込み
  • ステップ 5:
  • self::routeCheck($request , $config)

    ルート検出のために現在のコントローラーのrouteCheck()メソッドをロードします

    最初にルーティング アドレス構成の検出を実行し、最初にキャッシュされたルートを読み取り、ルーティング ファイル構成が存在する場合はそれをインポートします。存在しません
    • ルーティング構成はありません。モジュール/コントローラー/操作を直接解析します
    • #モジュールモジュール情報 (モジュール名、コントローラー名、および操作メソッド名)を返します
    • ステップ 6: デバッグ モードを有効にし、ルーティングとリクエスト情報のログを記録します。
  • ステップ 7:
  • self::exec($dispatch, $config)
  • コントローラー exec()メソッドで呼び出し分散を実行

    ユーザーリクエストの種類に応じて分散処理を行うここにモジュール module type

      Call
    • self::module ()
    • 実行モジュール、モジュールのデプロイと初期化を実行し、現在のコントローラー名と操作名を取得して設定します
    • ステップ 8: クラスのインスタンス化をクリアし、データを出力しますクライアント、つまりユーザーに対応する形式 目に見える出力インターフェース
  • 概要
この記事では、ThinkPHP5 の基本的な実行プロセスを大まかに分析します。 「整っていません。やり方がわからないので、言う必要はありません。私が作っただけです。それだけです。でも、間違っていたらご指摘ください。必ず修正します。」それが正直です。ちなみに、役に立ったと思われる場合は、「いいね!」を押して去ってください。ありがとうございます!

以上がTP5フレームワークの入力から出力インターフェースまでのロードプロセスを分析します。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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