En ocasiones necesitas parametrizar una ruta con una categoria y subcategoria y no quieres realizar una query a base de datos cada vez que lo necesites. Para ello podemos generar unas archivos json para meterlos en caché y leerlos en nuestro enrutador sin necesidad de consultar a la bd. Esto es una solución válida para cualquier framework, pero aquí lo explicaré para Phalconphp.

Un ejemplo de ruta sería la siguiente:

$router->add(
    '/('.$categoria.')/('.$subcategoria.')/{articuloSlug:[a-z\-\0-9]+}',
    [
        'controller'        => 'articulos',
        'action'            => 'ver',
        'categoria'         => 1,
        'subcategoria'      => 2
    ]
);

Tenemos una categoria y una subcategoría, más el slug del artículo (nótese que para el slug del artículo no se utiliza variable, debido a que el día de mañana podemos tener 2000 artículos y no queremos generar 2000 slugs en nuestro router), esto llamaría a nuestro controller y en el cogeriamos los parámetros.

¿Cómo genero las variables $categoria y $subcategoria?

Tenemos que generar un proceso, una función en algún controller para coger las tablas de categorias y subcategorias y escribirlas en un fichero json de la siguiente manera.

{"viajes":"1","coches":"2","ciudades":"3"}

En donde guardamos el slug y su id. Esto yo lo guardo en la carpeta config y en una carpeta llamada arraysApp. Ahí es dónde buscaremos para presentar nuestras variables en el router.

Para ello necesito tener la caché en mi proyecto. Con ello conseguimos coger el fichero con su contenido json y meterlo en caché para luego leerlo siempre de caché. Sería algo así:

// categorias
if (!$cache->exists('Categorias')) {
    $cache->save('Categorias',json_decode(file_get_contents(APP_PATH."/config/arraysApp/Categorias.ini.php"),true));
}
$categorias = $cache->get('Categorias');
if (isset($categorias['es'])) {
    $categorias = implode('|',array_keys($categorias['es']));
} else {
    $categorias = '';
}

Ahora tengo generadas las rutas con las categoría necesarias para que funcione sin necesidad de hacer una query a bd.

¿Y si no encuentra la ruta porque la meten mal?

Para ello tenemos que añadir la siguiente ruta en nuestro router, para decirle que vaya a nuestro controller de errores y a una view específica, así lanzará un 404.

$router->notFound(
    [
        'controller' => 'errores',
        'action'     => 'notFound',
    ]
);

Lo importante de lo anterior es tener el siguiente código en el controller que llamemos para que arroje el estado 404.

$response = new \Phalcon\Http\Response();
$response->setStatusCode(404, "Not Found");
$this->response->send();

Con estas orientaciones ya puedes montar un sistema de enrutado más potente y liviano para tu aplicación y base de datos.