---
title: "Bootstrap & Dispatcher"
description: "Wie ein Nibiru-Request von index.php durch den Dispatcher zu Ihrem Controller fließt."
---

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.

## index.php
```php
<?php
require_once 'core/framework.php';
```
Das ist die gesamte Datei. `index.php` existiert nur, um dem Webserver ein Ziel zu geben.

## core/framework.php

`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:
```php
Nibiru\Dispatcher::getInstance()->run();
```
Dieser einzelne Aufruf ist das Herzschlag Ihrer Anwendung.

## Dispatcher::run()

Der vereinfachte Ablauf:
```php
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
    }
}
```
## Die Aktionenfolge

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.

## Weiche 404

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:
```php
public function pageAction() {
    http_response_code(404);
    View::assign(['title' => 'Lost in the void']);
}
```
## Auto::loader()

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.

## SEO-URL-Verwaltung

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](/core/routing/).

## Wann der Dispatcher überschrieben werden sollte

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`.
