Núcleo
Ciclo de vida de una petición
De la URL a la respuesta
.htaccessreenvía la petición awebroot/index.php.core/Koshkil.phpse incluye: carga la configuración global y la del dominio, configuraerror_reportingy registra los manejadores de errores.new Application():startup()guarda el POST (paraKoshkil::old()) e inicializa la caché; después se abre la conexión a la base.Route::parseURI(): detecta los plugins activos, aplica las reglas de reescritura y descompone la URL en plugin, controlador, acción y argumentos.ActionDispatcher::_invoke(): busca el archivo del controlador, lo instancia y ejecuta su ciclo de vida y la acción.Response::render(): según el código de estado elige la plantilla (la de la acción,error/error404,error/error4xxoerror/error500) y la muestra dentro del layout, o devuelve el cuerpo tal cual si es JSON o un archivo.
// webroot/index.php
require_once('../core/Koshkil.php');
require('../vendor/autoload.php');
Koshkil::Uses('com.Application');
$app = new Application();
$app->run();
$app->done();
Dentro del controlador
Al construirse, el controlador crea Request, Response, Session y View, se registra en Koshkil::$controller e inicializa el idioma. Luego el dispatcher llama a startupProcess():
- Si
$openAccessesfalse, verifica la sesión conisLoggedIn(). Sin sesión llama aprocessLogin()y muestralogin.tpl. Con sesión,checkPermissions()valida$roles,$rulesy$strictRules. create(), el primer hook.- Los hooks de
$lifeCycle, por defectodispatch(),init()yrun(). - La acción, con los argumentos de la URL.
shutdownProcess(), al terminar.
Cualquier hook puede cortar el proceso:
| Devuelve | Efecto |
|---|---|
null (nada) |
Sigue con el paso siguiente. |
false |
Detiene los hooks restantes y no ejecuta la acción. |
un Response |
Se usa esa respuesta de inmediato. |
La acción solo puede devolver null o un Response; cualquier otro valor lanza una excepción.
Qué hook usar
create() para preparar dependencias, init() para cargar datos comunes a todas las acciones (así lo hacen SuperController y AdminSuperController) y la acción para lo específico. Si sobrescribís init(), llamá primero a parent::init().
Qué plantilla se muestra
Con código 200, la plantilla es la variable template de la vista si la acción la asignó; si no, <controlador>/<acción> en minúsculas. ProductosController::ver() muestra productos/ver.tpl, buscada en la carpeta templates/<templateFolder>/ del theme (front o admin).
La vista no muestra esa plantilla sola: la pasa como $template al layout ($templateFile, normalmente main.tpl), que la incluye con {html_include file="{$template}"}. Ver Vistas.
Cuando la URL no coincide
| Situación | Qué pasa |
|---|---|
No existe el controlador y la acción es index (URL de un solo segmento dentro de una carpeta) |
Se usa el último segmento como acción del controlador padre: /admin/perfil se resuelve como AdminController::perfil() cuando no hay un Admin/PerfilController. |
| No existe el controlador y la URL tiene un solo segmento | Responde System.DefaultController con código 404. |
No existe el controlador y la acción no es index |
La petición pasa a System.DefaultController con esa misma acción. |
| Existe el controlador pero no la acción | Se ejecuta su index() si existe (código 200); si no, 404. |
Warning
Por las dos últimas filas, una URL inexistente puede terminar mostrando el index() de un controlador con código 200. Si una acción recibe parámetros que no reconoce, respondé 404 explícitamente con $this->Response->setCode(404).
Errores
ExceptionRenderer registra manejadores para errores, excepciones no capturadas y errores fatales:
- Los warnings y notices solo se registran en el log.
- Las excepciones no capturadas y los errores fatales responden con código 500 y la plantilla
error/error500.tpl, que recibe$Response(getCode(),getMessage()) y$lastError(mensaje, archivo y línea).
Solo se tienen en cuenta los errores incluidos en Error.Reporting, y los logs se escriben en tmp/logs/ cuando Debug.Level es mayor que 0.