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

アーキテクチャ (MMVC)

モジュール、コントローラー、ビュー、モデル、レジストリ、ディスパッチャーがそれぞれ他に回る関係です。

Stable Reading time ~ 2 min Edit on GitHub

NibiruはMMVC:Model — View — Controller — そして2つ目のMModuleです。最初の3つは一般的ですが、2つ目のMがNibiruに独特な風味を与えます。

Nibiruランタイムの横断図で、各葉がシステムコンポーネントとしてラベル付けされています:Router、Controller、View、Model、Module、Registry。
Nibiruランタイムを花として表現。
┌──────────────┐
│ Browser │
└──────┬───────┘
│ HTTP
┌──────────────┐
│ index.php │
└──────┬───────┘
│ require
┌──────────────┐
│ framework.php│ ◀── boots Config, Router, Engine, Smarty,
└──────┬───────┘ all 28 form types, DB drivers, Auth.
┌──────────────┐
│ Dispatcher │
└──────┬───────┘
┌───────────────┼─────────────────┐
▼ ▼ ▼
┌────────┐ ┌──────────┐ ┌───────────┐
│ Router │ │ Modules │ │ Auto │
└────────┘ └──────────┘ │ loader │
└───────────┘
┌─────────────────────────────┐
│ applicationController.php │
│ navigationAction() │
│ <_action>Action() │
│ pageAction() │
└──────────────┬──────────────┘
│ View::assign(...)
┌──────────────┐
│ Smarty │ templates/<ctrl>.tpl + shared/*
└──────────────┘

1. コントローラー (application/controller/)

Section titled “1. コントローラー (application/controller/)”

コントローラーは、Nibiru\Adapter\Controller を拡張するクラスです。ディスパッチャーは、すべてのリクエストに対して固定のシーケンスを呼び出します:

  1. navigationAction() — メニュー/パンくずデータを設定します。
  2. <_action>Action() — 仅当 ?_action=foo が設定されている場合にのみ。
  3. pageAction() — 最終的なレンダリング時データの割り当て。

すべての3人が戻ったら、Display::display() は割り当てられた変数を Smarty に渡します。

2. ビュー (application/view/templates/)

Section titled “2. ビュー (application/view/templates/)”

Smarty .tpl ファイル。ディスパッチャは <controller>.tpl を自動的に解決します;ネストされたアクションは templates/<controller>/<action>.tpl の下に置かれます。View::assign(['x' => ...]) で渡されたすべての変数は {$x} として利用できます。

モデルは 自動生成 され、データベーススキーマから Model::__construct(false) によって生成されます — 1つのテーブルにつき1つのPHPクラスです。これらは Nibiru\Adapter\<Driver>\Db を拡張し、CRUDヘルパーを公開しています。生成されたモデルを手で編集し、再生成を無効にするには [GENERATOR] database = false を設定します。

4. モジュール (application/module/<name>/)

Section titled “4. モジュール (application/module/<name>/)”

A モジュールはその自らのトレイト、プラグイン、インターフェース、および設定をバンドルします。Registry は各モジュールの settings/*.ini を自動的に発見し、解析された構成を Registry::getInstance()->loadModuleConfigByName('users') 経由で公開します。モジュールは observer パターン を実装して、システムの他の部分がオブザーバーをアタッチし、状態変化に反応できるようにすることができます。

5. コズモスを結ぶシングルトン

Section titled “5. コズモスを結ぶシングルトン”
シングルトンジョブ
Config::getInstance()settings.<env>.ini を読み込み、モジュールの設定をマージします。
Router::getInstance()URL をコントローラー/アクション/パラメータに解析し、SEO 形式の URL を認識します。
Registry::getInstance()モジュールの発見と設定のキャッシュを行います。
Dispatcher::getInstance()コンダクターです。dispatch::run() はアプリケーションのハートビートです。
View::getInstance()Smarty をラップします。View::assign() はグローバルテンプレート変数のインボックスです。

なぜMMVCなのか、MVCではないのか?

Section titled “なぜMMVCなのか、MVCではないのか?”

シンプルなMVCは、コントローラーがロジックを共有し始めるまで機能します — 認証チェック、フォームファクトリー、サードパーティAPIクライアントなど。一般的な回答はサービス + DIコンテナですが、これは素早くプロトタイピングするためのフレームワークには多すぎる儀式です。

Nibiruの回答: モジュール。モジュールはドメイン(users, cms, analytics, tpms-quotes)を「所有」し、プラグインコントローラーを通じてそのサービスを公開します。これらのコントローラーは直接インスタンス化できます:

// In a controller
$user = new \Nibiru\Module\Users\Plugin\User();
if (!$user->isAuthorized()) {
View::forwardTo('/login');
}

モジュールは、その設定、データベーステーブル、テンプレート、フォームを所有しており、単体で削除可能です。

オブザーバパターンの実践的な使用法

Section titled “オブザーバパターンの実践的な使用法”

一部のモジュールは SplSubject を実装しているため、他のコードがイベントに反応できるようにする。デモンストレーションでは、prod.maschinen-stockert.de 上の analytics モジュールがこれを行っている:任意のコントローラーは attach() でトラッカー(Matomo プラグイン)をアタッチし、analytics モジュールはページビューごとに notify() する。コントローラーは存在するトラッカーについて何も知らない。

class Analytics implements \SplSubject {
private \SplObjectStorage $observers;
public function __construct() { $this->observers = new \SplObjectStorage(); }
public function attach(\SplObserver $o): void { $this->observers->attach($o); }
public function detach(\SplObserver $o): void { $this->observers->detach($o); }
public function notify(): void {
foreach ($this->observers as $o) { $o->update($this); }
}
}

フレームワークに意図的に含まれていないもの

Section titled “フレームワークに意図的に含まれていないもの”
  • DIコンテナなし。 シングルトンとプラグインで十分です。
  • ORMなし。 モデルはスキーマから生成され、クエリはDbアダプターまたはアクティブなドライバーを介した生のSQLを使用します。
  • Twig/Bladeのトリックを通じたテンプレート継承なし。 Smarty {include}が構成単位です。
  • イベントバスなし。 SplSubject/SplObserverは第一級です。
  • ファーストクラスのバックグラウンドジョブなし。 CLIがスケジューラです — cronやsystemdタイマーからドライブします。

学ぶことが少なく、出荷することが多い。

  • Bootstrap & Dispatcher — コードでのライフサイクル。
  • Routing — URL → コントローラーのマッピング規則。
  • Modules — 最初のモジュールを作成する。