Zum Inhalt springen
Nibiru docsv0.9.2

Bootstrap & Dispatcher

Wie ein Nibiru-Request von index.php durch den Dispatcher zu Ihrem Controller fließt.

Stable Reading time ~ 2 min Edit on GitHub

Eine Anfrage an Nibiru durchläuft drei Dateien: index.php, core/framework.php und core/c/dispatcher.php. In dieser Reihenfolge zu lesen, verrät Ihnen alles.

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

Das ist die gesamte Datei. index.php existiert nur, um dem Webserver ein Ziel zu geben.

framework.php erfordert die Klassen des Frameworks in Abhängigkeitsreihenfolge – Einstellungen, Registrierung, Router, Engine, Autoloader, alle Datenbanktreiber, alle 28 Formulartypen, Ansicht, Controller, Module, Authentifizierung, Debugging, Anzeige – und endet mit:

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

Dieser einzelne Aufruf ist das Herzschlag Ihrer Anwendung.

Der vereinfachte Ablauf:

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
}
}

Jede Anfrage durchläuft die gleichen drei Schritte, wenn ?_action=foo gesetzt ist:

  1. navigationAction() — Menüs und Breadcrumbs befüllen.
  2. fooAction() — die benannte Aktion ausführen.
  3. pageAction() — letzte Gelegenheit, Template-Daten zuzuweisen.

Ohne _action laufen nur die Schritte 1 und 3.

Dies bedeutet, dass stateless Renderzeitlogik in pageAction() und Navigationsdaten in navigationAction() gehören, auch wenn es sich anfühlt, als wäre es eine Verdoppelung der Arbeit. Zwei Controller im gleichen Projekt haben beide eine navigationAction(). Das ist korrekt.

Wenn die abgeglichene Controller-Datei nicht existiert, rendert Nibiru einen weichen 404 — es gibt eine 200 OK-Antwort und rendert den Controller, der in [ENGINE] error.controller (Standard: error) angegeben ist. Dies ist absichtlich: Es ermöglicht Ihnen, schöne Fehlerseiten ohne serverseitige Konfiguration bereitzustellen.

Wenn Sie einen echten 404 Not Found HTTP-Code benötigen, setzen Sie ihn in Ihrem Fehlercontroller:

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

Zwei Autoloader laufen vor dem Aufbau des Controllers:

  • loadModelFiles() durchsucht application/model/ und inkludiert jede .php-Datei dort. Generierte Modelle sind flache Dateien, keine benannten Pakete, daher ist dies eine einfache Schleife mit require_once.
  • loadModules() durchläuft application/module/<name>/ und lädt die Hauptklasse jedes Moduls sowie seine Trait-, Plugin- und Schnittstellen-Dateien. Der Registry werden gleichzeitig die Einstellungen des Moduls in der INI-Datei indiziert.

Beide verwenden die konfigurierten Pfade in [EINSTELLUNGEN] modules.path usw., sodass Sie sie je nach Umgebung überschreiben können.

Vor der Controller-Auflösung führt Router::route() die Methode handleSeoUrls() aus, die URLs des Formats /controller/<slug>/<id> (wobei das zweite Segment keine bekannte Aktion ist und das dritte numerisch) erkennt. Diese werden intern in /controller/detail/ umgeschrieben, wobei $_REQUEST['id'] und $_REQUEST['slug'] befüllt werden. Weitere Informationen finden Sie unter Routing.

Fast niemals. Die sauberen Erweiterungspunkte sind:

  • Benutzerdefinierter Fehlercontroller — setzen Sie [ENGINE] error.controller.
  • Pre-controller Hooks — laden Sie ein Modul, das einen Beobachter registriert, und fügen Sie ihn innerhalb von navigationAction() hinzu.
  • Cron-artige Eintragung — führen Sie das Framework ohne Benutzeroberfläche über die nibiru CLI aus, anstatt über index.php.