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:
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:
- Ejemplo de url estática (Hola, mundo).
- Ejemplo de url dinámica (cambia «Juan» en la url por una serie de palabras separadas por guiones).
- Ejemplo de url dinámica con subdirectorios (cambia «Pepe Perez»)