Ir al contenido
Nibiru docsv0.9.2

Bootstrap y Dispatcher

Cómo fluye una solicitud de Nibiru desde index.php a través del despachador hasta tu controlador.

Stable Reading time ~ 3 min Edit on GitHub

Una solicitud de Nibiru realiza un viaje a través de tres archivos: index.php, core/framework.php y core/c/dispatcher.php. Leerlos en ese orden te dice todo lo que necesitas saber.

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

Ese es todo el archivo. index.php existe solo para darle un objetivo al servidor web.

framework.php requiere las clases del framework en orden de dependencia — configuración, registro, enrutador, motor, cargador automático, todos los controladores de base de datos, todos los 28 tipos de formulario, vista, controlador, módulos, autenticación, depuración, visualización — y termina con:

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

Esa única llamada es el latido del corazón de tu aplicación.

El flujo simplificado:

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

Cada solicitud pasa por los mismos tres pasos si se establece ?_action=foo:

  1. navigationAction() — poblar menús, migas de pan.
  2. fooAction() — ejecutar la acción nombrada.
  3. pageAction() — última oportunidad para asignar datos de plantilla.

Sin _action, solo se ejecutan los pasos 1 y 3.

Esto significa que la lógica de tiempo de renderizado sin estado pertenece en pageAction(), y los datos de navegación pertenecen en navigationAction(), incluso si siente que está duplicando esfuerzos. Dos controladores en el mismo proyecto tendrán ambos un navigationAction(); eso es correcto.

Si el archivo de controlador coincidente no existe, Nibiru renderiza un 404 suave — devuelve un 200 OK y renderiza el controlador nombrado en [ENGINE] error.controller (por defecto: error). Esto es intencional: permite servir páginas de error agradables sin configuración de nivel de servidor.

Si quieres un código HTTP real de 404 Not Found, configúralo en tu controlador de errores:

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

Dos auto-cargadores se ejecutan antes de que se construya el controlador:

  • loadModelFiles() escanea application/model/ e incluye cada archivo .php ahí. Los modelos generados son archivos planos, no paquetes con espacios de nombres, por lo que es un simple bucle require_once.
  • loadModules() recorre application/module/<name>/ y carga la clase principal de cada módulo, así como sus archivos de traza, complemento e interfaz. El Registro indexa las configuraciones INI de cada módulo al mismo tiempo.

Ambos utilizan las rutas configuradas en [CONFIGURACIÓN] modules.path etc., por lo que puedes sobrescribirlas por entorno.

Antes de la resolución del controlador, Router::route() ejecuta handleSeoUrls(), que detecta URLs con el formato /controller/<slug>/<id> (donde el segundo segmento no es una acción conocida y el tercero es numérico). Estas se reescriben internamente como /controller/detail/ con $_REQUEST['id'] y $_REQUEST['slug'] poblados. Leer más en Routing.

Casi nunca. Los puntos de extensión más limpios son:

  • Controlador de errores personalizado — establece [ENGINE] error.controller.
  • Ganchos pre-controlador — carga un módulo que registra un observador, luego átalo dentro de navigationAction().
  • Entrada estilo crontab — ejecuta el framework en modo sin cabeza a través de la CLI nibiru en lugar de index.php.