El blog de Iván Argulo

Rutas amigables en CodeIgniter desde base de datos

Las URLs amigables son una de las características que todo proyecto web y página web debe tener. Las páginas web, tiendas virtuales y aplicaciones programadas en ASP clásico, y muchas de las programadas con PHP no disponen de estas rutas amigables. Así, es común ver URLs que apuntan a archivos terminados en .asp, .php, .jsp... Este tipo de URLs afectan negativamente al posicionamiento de las páginas web y tiendas virtuales, por lo que debemos hacer todo lo posible por evitarlas en nuestros proyectos.

CodeIgniter viene con una característica muy interesante: el "enrutado" (routing) de controladores. Así, por ejemplo la función "detalles($url)" dentro del controlador "producto" se convierte en "producto/detalles/nombre-del-producto".

Utilizando esta característica, podemos obtener URLs cortas y amigables. Es más, en el ejemplo anterior podríamos reducir la URL incluso a "productos/nombre-del-producto".

Cómo conseguir rutas amigables en CodeIgniter

Tener rutas amigables en CodeIgniter es muy fácil. Basta con abrir el archivo routes.php, ubicado en la carpeta config dentro de nuestra aplicación. Esto está muy bien explicado en la documentación oficial de CodeIgniter (inglés), por lo que si no lo conoces te recomiendo que visites el enlace y lo utilices en cualquier proyecto web.

Sin embargo, uno de los principales problemas a la hora de crear rutas amigables es que siempre tiene que haber un segmento de la URL que nos sirva para identificar el contenido.


Supongamos un controlador llamado "contenidos" y una función "detalles($url)", que muestra una vista con el contenido de la base de datos. Lo más normal en este caso sería tener esta configuración:

$route['contenidos/(:any)'] = 'contenidos/detalles/$1';


¡Perfecto! Ahora nuestra web es accesible desde la URL www.ejemplo.com/contenidos/url-del-contenido. Pero... a veces el segmento "contenidos" nos estorba, para una mayor claridad en los enlaces y una optimización SEO. ¿Solución? Utilizar una parte de la URL fija para identificar el contenido, por ejemplo ".htm".

$route['(:any).htm'] = 'contenidos/detalles/$1';


Vamos acercándonos, pero en muchas ocasiones tener este "trozo" de segmento ahí nos estorba o nos parece visualmente poco atractivo. En este caso la URL sería www.ejemplo.com/url-del-contenido.htm. Si no queremos tener una URL así tendríamos que definir en el archivo routes.php todas las URLs de nuestra página web, y esto puede ser inviable si tu web lee los contenidos o las páginas de una base de datos.

En este caso, si queremos leer las rutas desde la base de datos, es necesario hacer una pequeña modificación en el archivo routes.php.

require_once( BASEPATH .'database/DB'. EXT );

$db =& DB();
$rs = $db->get('contenidos');

foreach ($rs->result() as $fila)
	$route[$fila->url] = "contenidos/{$fila->url}";

Explicación:
require_once( BASEPATH .'database/DB'. EXT ); incluye la librería que permite hacer consultas a la base de datos.
$db =& DB(); crea un objeto de base de datos.
$rs = $db->get('contenidos'); hace una consulta a la tabla de contenidos.
foreach ($rs->result() as $fila) bucle para recorrer todos los contenidos.
$route[$fila->url] = "contenidos/{$fila->url}"; crea la ruta, vinculada al a URL configurada en la tabla.

Algunas consideraciones a tener en cuenta

Este fragmento de código es un ejemplo sencillo de cómo crear rutas amigables extraídas de una base de datos en un aplicación web. No se están tomando en cuenta el rendimiento de la aplicación cuando la tabla `contenidos` tiene cientos o miles de registros, o cuando la aplicación tiene muchas visitas de forma continuada.

La tabla de contenidos deberá estar optimizada, así como las conexiones a la base de datos, para no penalizar el rendimiento con esta funcionalidad.