モジュール
Nibiru モジュールの構築 — MMVC の 2 番目の M。特性、プラグイン、インターフェース、設定、オブザーバー。
A モジュールは自己完結型のドメイン単位です。各モジュールは、設定、プラグイン(サービス)、トレイト(再利用可能なメソッド)、インターフェースを所有しており、必要に応じて独自のMVCスライスも持つことができます。Nibiruは、サービスコンテナなしで太いコントローラー問題を回避するために、モジュールを使用しています。
application/module/<name>/├── <name>.php # main class (implements IModule, optionally SplSubject)├── interfaces/ # contracts for plugins / external consumers│ └── <name>.php├── plugins/ # stateless services usable from controllers│ ├── <thing>.php│ └── <other>.php├── settings/ # auto-discovered .ini files│ ├── <name>.ini│ └── <name>.production.ini└── traits/ # reusable method groups └── <name>.phpRegistry は起動時に application/module/ を走査し、各モジュールの settings/*.ini を発見します。モジュール名(大文字)に一致するセクションを解析し、Registry::getInstance()->loadModuleConfigByName('users') 経由で検索するためにキャッシュします。
最小限のモジュール
Section titled “最小限のモジュール”<?phpnamespace Nibiru\Module\Users;
use Nibiru\Module as ModuleAdapter;use Nibiru\Interfaces\IModule;use Nibiru\Registry;
class Users extends ModuleAdapter implements IModule, \SplSubject{ use Traits\Users;
const CONFIG_MODULE_NAME = 'users';
protected static \stdClass $usersRegistry; protected \SplObjectStorage $observers;
public function __construct() { $this->setUsersRegistry(); $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); } }
protected function setUsersRegistry(): void { self::$usersRegistry = Registry::getInstance() ->loadModuleConfigByName(self::CONFIG_MODULE_NAME); }}IModule インターフェースは意図的にマーカーです — 実際の動作はすべてトレイトとプラグインにあります。
プラグイン:ステートレスサービス
Section titled “プラグイン:ステートレスサービス”プラグインは、モジュール機能にアクセスするためにコントローラーがインスタンス化できるクラスです:
<?phpnamespace Nibiru\Module\Users\Plugin;
use Nibiru\Module\Users\Users;use Nibiru\Pdo;
class User extends Users{ public function isAuthorized(): bool { return isset($_SESSION['auth']['user_id']); }
public function checkForStandardUser(): bool { return $this->isAuthorized() && ($_SESSION['auth']['role'] ?? '') === 'standard'; }}コントローラー内で:
$this->user = new \Nibiru\Module\Users\Plugin\User();if (!$this->user->isAuthorized()) { View::forwardTo('/login');}プラグインはモジュールクラスを継承するので、レジストリ、設定、およびオブザーバーの機能にアクセスできます。
特性: 再利用可能なメソッド
Section titled “特性: 再利用可能なメソッド”トレイトは、モジュールクラスが必要な再利用可能なメソッド本体を保持します。一般的なパターン:フォームファクトリーです。
<?phpnamespace Nibiru\Module\Users\Traits;
use Nibiru\Form;
trait Users{ public function loginForm(): string { Form::create(); Form::addOpenDiv(['class' => 'form-group']); Form::addInputTypeText([ 'class' => 'form-control', 'name' => 'login', 'placeholder' => 'Username', ]); Form::addCloseDiv(); Form::addOpenDiv(['class' => 'form-group']); Form::addInputTypePassword([ 'class' => 'form-control', 'name' => 'password', 'placeholder' => 'Password', ]); Form::addCloseDiv(); return Form::addForm([ 'method' => 'POST', 'action' => '/login', 'name' => 'loginForm', ]); }}メインの Users クラスは、use Traits\Users; を通じて取り込みます。
モジュール設定 (INI)
Section titled “モジュール設定 (INI)”各モジュールは独自の INI ファイルを持つことができます。Registry は settings/ 内のすべての *.ini を解析し、モジュール名(大文字)で命名されたセクションを探します。
; application/module/users/settings/users.ini[USERS]session.lifetime = 7200password.min.length = 12allowed.roles[] = "admin"allowed.roles[] = "editor"allowed.roles[] = "standard"どこからでも読み返す:
$cfg = \Nibiru\Registry::getInstance()->loadModuleConfigByName('users');$cfg->session_lifetime; / 7200$cfg->password_min_length; / 12$cfg->allowed_roles; / [admin, editor, standard]環境オーバーレイ:APPLICATION_ENV=production の場合、users.production.ini が users.ini よりも優先されます。
観察者パターン
Section titled “観察者パターン”SplSubject を実装するモジュールは、イベントをアタッチされたオブザーバーにブロードキャストすることができます。デモンストレーションでは、analytics モジュールは各ページビュー時にアタッチされたトラッカーに通知します。
// in a controller$analytics = new \Nibiru\Module\Analytics\Analytics();$analytics->attach(new \Nibiru\Module\Analytics\Plugin\Matomo());$analytics->attach(new \Nibiru\Module\Analytics\Plugin\Plausible());
$analytics->trackPageView(); / internally calls notify()各観察者の update($subject) は、分析インスタンスを受け取り、関心のあるイベントデータを取得します。
実際の生産モジュール
Section titled “実際の生産モジュール”展示アプリケーションから:
auth(TPMS) — セッション管理、QRコードログイン、ロールベースのアクセス。SplSubjectを実装してログイン/ログアウトイベントをログ記録や監査モジュールに拡散させます。cms(prod.maschinen-stockert.de) — コントローラパス + 言語でキー付けされたコンテンツストア。非開発者がサイトのコピーを更新できるようにします。graph_mail(TPMS) — トランザクションメール用の Microsoft Graph API ラッパー。pdfgenerator(prod.maschinen-stockert.de) — DBドライブテンプレートから機械カタログを生成します。machineryscout— インデックス管理トレイトを使用した Elasticsearch インデックス管理。assetmanager— 中央の CSS/JS パイプライン、言語ごとにテーマをスワップするために使用されます。analytics— オブザーバドライブトラッカー拡散(Matomo 等)。
モジュール登録: フレームワークがモジュールを見つける方法
Section titled “モジュール登録: フレームワークがモジュールを見つける方法”ディスク上のモジュールフォルダは必要ですが、十分ではありません。フレームワークもそれを読み込むように知らなければなりません — これは、あなたの [AUTOLOADER] 設定で3つの位置配列で行われます:
; application/settings/config/settings.development.ini
[AUTOLOADER]iface.pos[] = "users" ; load application/module/users/interfaces/iface.pos[] = "billing" ; load application/module/billing/interfaces/trait.pos[] = "users" ; load application/module/users/traits/trait.pos[] = "billing"class.pos[] = "users" ; load application/module/users/users.phpclass.pos[] = "billing"class.plugin.pos[] = "" ; reserved名前は小文字のフォルダ名であり、application/module/の下に表示される完全に同じです。フレームワークのAuto::loader()(Dispatcherから呼び出されます)は、各モジュールを順番に読み込みます。
プラグインの名前空間規約
Section titled “プラグインの名前空間規約”プラグインクラスは、複数形の名前空間 Plugins の下にあります:
namespace Nibiru\Module\Billing\Plugins; / ← pluralclass Invoice extends \Nibiru\Module\Billing\Billing { /* ... */ }名前空間が一致しないと、オートローダーのミスが発生します。CLI スキャフォールド (./nibiru -m billing) は正しい名前空間を生成してくれます。
モジュールの INI ファイルを 登録しないでください — Registry は、[AUTOLOADER] がモジュールクラスを読み込んだ後、application/module/<name>/settings/*.ini を走査して自動的に発見します。各 INI の [<MODULE>](大文字)セクションは次のようになります:
$cfg = \Nibiru\Registry::getInstance()->loadModuleConfigByName('billing');$cfg->invoice_prefix; / [BILLING] invoice.prefix → propertyレジストリは、APPLICATION_ENV が一致する場合に <module>.<env>.ini(例:billing.production.ini)を優先します。
マイグレーション
Section titled “マイグレーション”モジュールにデータベーステーブルがある場合、既存の範囲を超えて番号を付けたSQLファイルをapplication/settings/config/database/に配置してください。AIモジュールで使用されている規約です。
200-ai_rag_collection.sql201-ai_rag_chunk.sql202-ai_conversation.sql203-ai_message.sql./nibiru -mi localで実行します。フレームワークは、[GENERATOR] database = trueが設定されている場合、application/model/<table>.phpにモデルを自動生成し、\Nibiru\Pdo::fetchAll(…)で使用できるようにします。
モジュールの生成
Section titled “モジュールの生成”./nibiru -m billingスキャフォールド:
application/module/billing/├── billing.php├── interfaces/billing.php├── plugins/├── settings/billing.ini└── traits/Graylogのログフックをスキャフォールドに事前に組み込む場合は、-g スイッチ(./nibiru -m billing -g)を追加してください。
モジュールを作成しない場合
Section titled “モジュールを作成しない場合”すべてのコントローラーをモジュールに昇格させないでください。閾値は次の通りです: 少なくとも1つのトレイト、1つのプラグイン、1つのINIキーを持っていますか? はいの場合、独自のモジュールフォルダを獲得します。そうでない場合は、共有トレイトファイルまたは小さなapplication/lib/ヘルパーが十分です。