Una de las partes más importantes de una web, sobre todo de cara al SEO, son las url utilizadas. A nadie le gusta que en su blog las urls aparezcan con feos parámetros obligatorios en la query, como wordpress por defecto:

http://emiliocobos.net/?p=787

Hoy os presento un par de clases en php que os facilitarán la tarea de crear webs con urls bonitas:

Demo Descarga Ver en GitHub

Para lograr urls bonitas hay dos alternativas:

1- .htaccess

Usar mod_rewrite es a priori la más «simple» de conseguir urls bonitas, ya que viene integrada en nuestro servidor, pero tiene muchos inconvenientes:

  • Es poco mantenible: El día que quieras cambiar la estructura de una url (pasar un nombre de usuario en vez de una id) tendrás que cambiar tanto tu código PHP como tu .htaccess
  • Al final trabajas con la query string: Puede haber conflictos entre parámetros pasados por el usuario y los tuyos, o que cualquier otro parámetro sea ignorado. Supongamos que /user/1 redirige mediante apache a /user.php?uid=1. Si quisieras usar un parámetro get para otra cosa, seguramente no funcione ir a /user/4?edit, sino que habrá que crear otra regla específica.

2- Redirigir todas las solicitudes a index.php y desde ahí leer

Ésta es la opción más sana (sobre todo porque mantienes toda tu lógica en el mismo sitio), se consigue con un .htaccess tal que así:

<IfModule mod_rewrite.c>
	RewriteEngine on

	RewriteCond %{REQUEST_FILENAME} !-f
	RewriteCond %{REQUEST_FILENAME} !-d

	RewriteRule ^(.*)$ index.php/$1 [L]
</IfModule>

Se pueden leer las urls a mano (mediante $_SERVER['REQUEST_URI']), pero yo he hecho un par de clases para facilitar la tarea, permitiéndote usar expresiones regulares, y dejándote elegir métodos específicos (GET, POST…).

Un ejemplo sencillo:

Nuestro index.php con nuestra nueva configuración para hacer el rewrite anterior quedaría así:

<?php
include 'src/Router/Route.php';
include 'src/Router/Router.php';

// Si está en el directorio raíz dejar así, si no especificar como primer parámetro '/la-subcarpeta'
$router = new Router\Router();

$router->add('/', function() {
    // Mostrar el home
});

$router->add('/user/([0-9]+)', function($user_id) {
    // Ya tenemos la id del usuario en la variable $user_id, sin tener que acceder a $_GET ni nada por el estilo
    // En este caso habría que comprobar si el usuario existe, y si no mandar un 404
});

$router->add('/*.', function() {
    // 404
});
?>

Más ejemplos:

Podéis ver más ejemplos en github, donde se encuentra el código, o la demo en vivo:

Demo y descarga

Demo Descarga Ver en GitHub