コンテンツにスキップ
Nibiru docsv0.9.2

Bootstrap & Dispatcher

Nibiruリクエストがindex.phpを経てディスパッチャに到達し、その後あなたのコントローラーにどのように流れることか。

Stable Reading time ~ 1 min Edit on GitHub

ニブルのリクエストは3つのファイルを1回通過します:index.phpcore/framework.php、およびcore/c/dispatcher.php。それらをその順序で読み込むと、すべてがわかります。

<?php
require_once 'core/framework.php';

これが全体のファイルです。index.phpはウェブサーバーにターゲットを提供するだけです。

framework.php は、依存関係の順序でフレームワークのクラスを読み込みます。設定、レジストリ、ルーター、エンジン、オートローダー、すべてのデータベースドライバー、すべての28種類のフォームタイプ、ビュー、コントローラー、モジュール、認証、デバッグ、表示 — そして最後に以下を実行します:

Nibiru\Dispatcher::getInstance()->run();

その単一の呼び出しは、アプリケーションのハートビートです。

簡略化された流れ:

public function run() {
date_default_timezone_set(Config::getInstance()->getConfig()
[View::NIBIRU_SETTINGS]['timezone']);
if (Config::getInstance()->getConfig()
[self::CONFIG_GENERATOR_SECTION][self::GENERATOR_DATABASE]) {
new Model(false); / 1. (re)generate models from schema
}
Router::getInstance()->route(); / 2. parse the URL
Auto::loader()->loadModelFiles(); / 3. load model files
Auto::loader()->loadModules(); / 4. load module classes
$tpl = Router::getInstance()->tplName();
$controllerFile = __DIR__ . "/../../application/controller/{$tpl}Controller.php";
if (is_file($controllerFile)) { / 5. controller file exists
require_once $controllerFile;
$class = "Nibiru\\{$tpl}Controller";
$controller = new $class();
if (array_key_exists('_action', $_REQUEST)) {
$action = $_REQUEST['_action'] . 'Action';
$controller->navigationAction();
if (method_exists($controller, $action)) {
$controller->$action(); / 6. optional named action
}
$controller->pageAction();
} else {
$controller->navigationAction();
$controller->pageAction();
}
Display::getInstance()->display(); / 7. render Smarty
} else {
/ 8. soft 404 render the configured error controller
}
}

すべてのリクエストが同じ3つのステップを経る場合、?_action=foo が設定されているときです。

  1. navigationAction() — メニュー、パンくずを設定します。
  2. fooAction() — 名前付きアクションを実行します。
  3. pageAction() — テンプレートデータを最後に割り当てます。

_action 無しでは、ステップ 1 とステップ 3 のみが実行されます。

これは、ステートレスなレンダリング時ロジックは pageAction() に含まれるべきでありナビゲーションデータは navigationAction() に含まれるべきであるということを意味します。それが労力の重複に感じさせても、同じプロジェクト内の2つのコントローラーともに navigationAction() を持つのは正しいです。

マッチしたコントローラー ファイルが存在しない場合、Nibiru は ソフトウェア 404 をレンダリングします — 200 OK を返し、[ENGINE] error.controller(デフォルト: error)で指定された名前のコントローラーを表示します。これは意図的な動作です:これにより、サーバー レベルの構成なしに美しいエラーページを提供できます。

実際の 404 Not Found HTTP コードを使用するには、エラーコントローラーで設定します。

public function pageAction() {
http_response_code(404);
View::assign(['title' => 'Lost in the void']);
}

コントローラーが構築される前に2つのオートローダーが実行されます:

  • loadModelFiles()application/model/ をスキャンし、そのディレクトリ内のすべての .php ファイルをインクルードします。生成されたモデルは名前空間パッケージではなくフラットなファイルなので、これは単純な require_once ループです。
  • loadModules()application/module/<name>/ を走査し、各モジュールのメインクラスとそのトレイト、プラグイン、インターフェースファイルを読み込みます。レジストリは同時に各モジュールの設定 INI をインデックスします。

両者は、[SETTINGS] modules.path 等の設定されたパスを使用しているため、環境ごとに上書きすることができます。

コントローラーの解決前に、Router::route()handleSeoUrls() を実行します。このメソッドは /controller/<slug>/<id> 形式の URL(2 番目のセグメントが既知のアクションではなく、3 番目が数値である場合)を検出します。これらの URL は内部的に /controller/detail/ にリライトされ、$_REQUEST['id']$_REQUEST['slug'] が設定されます。詳細については Routing を参照してください。

ディスパッチャーをオーバーライドする場合

Section titled “ディスパッチャーをオーバーライドする場合”

ほとんどありません。クリーナーの拡張ポイントは次のとおりです:

  • カスタムエラーコントローラー[ENGINE] error.controller を設定します。
  • プリコントローラーフック — オブザーバーを登録するモジュールを読み込み、その後 navigationAction() 内でアタッチします。
  • cron スタイルのエントリnibiru CLI を使用してフレームワークをヘッドレスで実行し、代わりに index.php を使用します。