Optimizando una web de URL extensas a URL amigables con Apache y PHP

Posted by willywg, Sun Jun 25 11:58:00 UTC 2006

Resumen. En este manual Ud. aprederá cómo optimizar de manera sencilla una web dinámica hecha en PHP, cuyas URL's pasadas a los enlaces contengan extensas variables pasadas mediante GET, a una web cuyas URL sean amigables (fáciles de recordar).

Introducción.

Los que programamos en PHP, o bajo cualquier otro lenguaje de programación orientado a web, por lo general tendemos a pasar datos de una web origen a otra destino mediante variables del tipo GET generando enlaces tal como: http://www.tiperu.com/index.php?mod=ecommerce&producto=tienda&op=3 que difícilmente son indexadas por algunos buscadores y lo que es peor aún: son nada asimilables por un usuario común (a este grupo de URL las llamaremos URL extensas para efectos del presente artículo). Si lo vemos desde esa perspectiva justo sería afirmar que las web dinámicas tienen desventajas en ese ambito sobre las web estáticas del tipo http://www.tiperu.com/ecommerce.html que son mucho más fáciles de recordar por su simpleza y carencia de variables vía GET, a este tipo de URL las conocemos (y me referiré a ellas en adelante) como URL amigables.

Quiero dejar en claro que lejos de la división convencional entre lo que son web estáticas o dinámicas en este manual me referiré a ambas en función a la diferencia de URL especificadas en el párrafo anterior - hecha la aclaración continuo con el artículo.

Felizmente para los que usamos Apache como servidor web, conjuntamente con PHP, esto tiene solución gracias al módulo mod_rewrite (URL Rewriting Engine) que nos permitirá mediante unas cuantas reglas transformar nuestras URL extensas en URL amigables.

Si bien es altamente aconsejable aprender el correcto manejo del mod_rewrite y sus correspondientes reglas, en este artículo no se hará explicación extensiva del mismo pues su objetivo principal, y claramente detallado en el título, es mostrar al lector cómo optimizar una web de URL extensas a URL amigables; con esto quiero dejar a entender que se asume que el lector posee un website ya creado con URL extensas y desea pasarlas fácilmente a URL amigables "en un dos por tres" .

Preparando el archivo ".htaccess".

El archivo .htaccess nos permite pasarle información al servidor Apache para que cumpla ciertas reglas de configuración en la carpeta que lo contenga, por tal motivo debemos copiar este archivo en la carpeta que contengan los archivos php en los cuales realizaremos los cambio de URL:
  1. Options +FollowSymLinks
  2. RewriteEngine on
  3. #4 variables
  4. Rewriterule ^(.*)/(.*),(.*)/(.*),(.*)/(.*),(.*)/(.*),(.*)/$ $1.php?$2=$3&$4=$5&$6=$7&$8=$9
  5. #3 variables
  6. Rewriterule ^(.*)/(.*),(.*)/(.*),(.*)/(.*),(.*)/$ $1.php?$2=$3&$4=$5&$6=$7
  7. #2 variables
  8. Rewriterule ^(.*)/(.*),(.*)/(.*),(.*)/$ $1.php?$2=$3&$4=$5
  9. #1 variable
  10. Rewriterule ^(.*)/(.*),(.*)/$ $1.php?$2=$3
En las dos primeras líneas nos aseguramos de que esté activado el mod_rewrite en el Apache (si esto no funciona deberá comunicarse con su administrador para que active el módulo en el servidor).

Las líneas antecedidas por "#", como las 3, 5, 7 y 9 ; son simplemente comentarios, no los tome en cuenta.

En las líneas 4, 6, 8 y 10 se establecen las reglas que nos permitirán tranformas nuestras URL extensas en amigables. Analizaremos aquella que permite transformar dos variables, las demás son similares:

Rewriterule ^(.*)/(.*),(.*)/(.*),(.*)/$ $1.php?$2=$3&$4=$5

La expresión en rojo es la nos permitirá escribir la regla en el Apache. La cadena en color verde oscuro permite escribirá la URL amigable, inicia desde el caracter ^ hasta el $. Y finalmente la cadena en azul es nuestro URL extenso. La transformación se hará de la siguiente manera:

De URL extensa:
./index.php?categoria=monitores&productoID=12345

En URL amigable:
./index/categoria,monitores/productoID,12345/

Como se puede apreciar la regla tomara el nombre del script y le quitara la extensión ".php" para tomarlo como un directorio (nótese la parte en negritas):
Rewriterule ^(.*)/(.*),(.*)/(.*),(.*)/$ $1.php?$2=$3&$4=$5 ./index.php?categoria=monitores&productoID=12345 ./index/categoria,monitores/productoID,12345/

Seguidamente toma el primer par ?valor=variable y lo transfroma en una subcarpeta valor,variable/:
Rewriterule ^(.*)/(.*),(.*)/(.*),(.*)/$ $1.php?$2=$3&$4=$5 ./index.php?categoria=monitores&productoID=12345 ./index/categoria,monitores/productoID,12345/

Y finalmente hace lo propio con el par &valor=variable y lo transforma en una subcarpeta valor,variable/:
Rewriterule ^(.*)/(.*),(.*)/(.*),(.*)/$ $1.php?$2=$3&$4=$5 ./index.php?categoria=monitores&productoID=12345 ./index/categoria,monitores/productoID,12345/

Como ya se habra dado cuenta, los valores antecedidos por el símbolo dólar ($) en la parte de las URL extensas reemplazan a los (.*) de las URL amigables.

Bueno ya tenemos el archivo .htacces que nos permitirá lograr los resultados que deseamos a nivel del servidor, ahora procederemos a crear el script php que nos permita cambiar nuestras URL extensas en amigables sin tener que hacer ninguna modificación directa en los "N" enlaces que posea nuestro sitio web.

Generando el script en php.

El script php que se usaremos se encargará básicamente de tomar la URL extensa, si esta ha sido pasada mediante el método GET, y la transformará en una URL amigable a la cual redirecionará usando la función header. Puesto que header redirecionará hacia la misma web, y esto causará lo que se conoce como un bucle infinito, se hará uso de variables de sesión que nos ayuden a evitar tal inconveniente; por tal motivo nuestro script se seccionará en 2 partes: la primera irá en las primeras líneas de todas las páginas a las que aplicaremos el script, y la segunda parte (encargada de limpiar la variable de sesión) irá al final de las páginas. Aclarados los detalles, explicaré mediante comentarios el script php:
< ? php
//Iniciamos o continuamos la sesión encargada de evitar el bucle infinito
session_name("url_amigable");
session_start();
//Almacenamos datos del server, script y variables (pasadas por GET)
$Server=$_SERVER['SERVER_NAME'];
$Script=$_SERVER['PHP_SELF'];
$Variables=$_SERVER['QUERY_STRING'];
//Verificando si tiene variables por GET
//y no se han pasado datos mediante un form por POST
//ya q al redireccionar un post puede ocasionar errores.
//Tambien verificamos que la variable de sesión 'Listo'
//sea diferente a 1, esto nos eviara un bucle infinito.
if(!empty($Variables) && $_SERVER['REQUEST_METHOD']=='GET' && $_SESSION['Listo']!=1){
//Si tiene variables pasadas por GET se procede a hacer el cambio.
//1. Agrupando $Variables por "variable=valor" en el array $Variable.
$Variable=explode("&",$Variables);
//2. Sustituyendo "=" por "," y concadenandolo en variable $Amigable.
($i=0; $i < count($Variable); $i++){
$Amigable.="/".str_replace("=",",",$Variable[$i]);
}

//3. Quitando la extension ".php" a $Script para simular un directorio.
$Dir=str_replace(".php","",$Script);
//4. Generando la URL Amigable.
$URL_AMIGABLE="http://".$Server.$Dir.$Amigable."/";
//5. Colocando la variable de sesión 'Listo' a 1 para evitar el bucle infinito
// al redireccionar la web.
$_SESSION['Listo']=1;
//6. Redireccionando a la url amigable
header("Location: $URL_AMIGABLE");
//7. Exit hará que culmine hasta este punto el script, si no estuviera 'exit'
// el script continuaría ejecutándose y llegaría hasta el final del mismo, es decir,
// a la parte donde colocamos a la variable de sesión 'Listo' en cero, originandose
// entonces un bucle infinito.
exit;
}
//Cambie $_URL_BASE por la ruta raiz de su web, ya que al simular la url amigable
//directorios, hará que no muestre adecuadamente los origenes de los recursos que
//llama su página web.
$_URL_BASE="http://".$Server."/pruebas/url_amigable/index.php";
?>
< html >
< head >
< title >URL Amigables< / title>
< base href = "< ? echo $_URL_BASE;?>" target="_top" />
< / head>
< body>
< ! - - Aquí el contenido de su página web - ->
< / body>
< / html>< ? php
//Limpia el posible bucle, es decir, se puede volver a hacer el envío. $_SESSION['Listo']=0;
?>

Recomendaciones finales.


Como habrán podido ver el script no es complicado, y la adaptación a una web ya constituida tampoco lo será. Ya he probado la técnica en uno de mis proyectos (de manera local) y me ha funcionado bastante bien.

Lo que sí quiero aclarar es que al momento de testear esta técnica en una url de 5 variables a más me generó errores (básicamente no encuentra la url amigable generada); una url de 4 variables redireciona correctamente, pero si luego de ello refresco el navegador genera el mismo error, es decir, no (re)carga la url amigable.

Mi consejo es que usen esta técnica en una url de 3 a menos de 3 variables pasadas por GET y personalicen este script a sus necesidades. Y como es lógico, les aconsejo bastante informarse más sobre el uso del mod_rewrite en Apache, creanme que les aliviará más de un dolor de cabeza.

Finalmente les diré que pueden descargarse el script desde aquí: url_amigable.zip.

Derechos de Autor.

Se autoriza la libre distribución y uso de este material, así como también su publicación en otros sitios web (siempre que no sea con fines comerciales ni lucrativos) de manera total y/o parcial siempre que no se altere el sentido de su contenido y se indiquen expresamente los siguientes datos (salvo que mi persona permita lo contrario):

Autor: William Wong Garay Website: http://www.tiperu.com Blog: http://willy.tiperu.com

Libros recomendados.

Apache: The Definitive Guide (3rd Edition) Beginning PHP5, Apache, and MySQL Web Development (Programmer to Programmer) Apache Server 2.0: The Complete Reference

Clasificado en: Artículos Programación | Tags:
#

#

Comentarios

  1. Max 06.27.06 / 04AM
    Excelente Willy, buen aporte

  2. meneame.net 07.01.06 / 12PM
    Optimizando una web de URL extensas a URL amigables con Apache y PHP... En este post aprederás cómo optimizar de manera sencilla una web dinámica hecha en PHP, cuyas URL’s pasadas a los enlaces contengan extensas variables pasadas mediante GET, a una web cuyas URL sean amigables (fáciles de recordar)....

  3. Beldar 07.01.06 / 17PM
    El trozo del for está mal (sale cortado): for($i=0;$i $Amigable.=”/”.str_replace(”=”,”,”,$Variable[$i]); } Supongo que querrias poner: for($i=0;$i o algo parecido. Por otro lado, está currado el tutorial. Saludos

  4. Beldar 07.01.06 / 17PM
    Lol me salió cortado a mi también, bug de wordpress? Se piensa que es un tag raro. Era: for($i=0;$i(más pequeño que)count($Variable);$i++){ $Amigable.=”/”.str_replace(”=”,”,”,$Variable[$i]); } Saludos.

  5. Un visitante 07.01.06 / 21PM
    No me gusta por varios motivos. - Supones que en el hosting que escogerá el cliente para poner su página tendrás acceso para modificar el htaccess, y , por desgracia, no siempre es así. Y cuando lo es, estan muy capados. - Es un gasto enorme de tiempo de ejecución, que se traduce en tiempo de descarga la web. - No es para nada claro. - Ya puesto prefiero mil veces un truco como este: http://sentidoweb.com/2006/03/06/camo-acceder-a-contenidos-mediante-la-url.php

  6. willy 07.03.06 / 13PM
    Saludos manes... Beldar, gracias por el aviso, ya corregí el lio con el for, solo coloqué un espacio entre el signo 'menor que'... En cuanto a 'Un visitante', sería bueno que leyeras con detenimiento mi post y te detuvieras en este punto: "Si bien es altamente aconsejable aprender el correcto manejo del mod_rewrite y sus correspondientes reglas, en este artículo no se hará explicación extensiva del mismo pues su objetivo principal, y claramente detallado en el título, es mostrar al lector cómo optimizar una web de URL extensas a URL amigables; con esto quiero dejar a entender que se asume que el lector posee un website ya creado con URL extensas y desea pasarlas fácilmente a URL amigables “en un dos por tres” ." Yo no pretendí en el post explicar el uso del htaccess ni sus ventajas o desventajas. Si no te fue claro el post dime en que puntos se te hace dificultoso y te lo explico con gusto; y en cuento al truco que linkeas, pues esta muy bien, pero no se asemeja a la temática de mi post, pues yo doy respuesta a una web ya hecha y que usa variables get en la url... De otro lado agradeceria bastante que coloques tu correo-e para poder responderte... al menos como un gesto de cortesía.

  7. Alex 07.15.06 / 02AM
    Sólo un detalle, las expresiones regulares que usas son ineficientes (sugiero que le des un vistazo a un tutorial de expresiones regulares) y crean un sobrecosto innecesario en el servidor web, si bien es cierto que esta característica de apache es muy poderosa, también puede ser la causa de muchos problemas si está mal utilizada. Saludos

  8. willy 07.15.06 / 08AM
    Saludos Alex, tienes razón en lo que dices, pero dejo en claro que este no es un manual que pretende explicar el buen uso del mod_rewrite (por poco ético que suene), lo único que pretendo en este manual es el dar una manera sencilla de pasar las url extensas de una web ya creada a url amigables sin hacer mayores cambios. Incluso recomiendo el estudio adecuado del mod_rewite al final del artículo. Válida tu observación pero recuerda que doy las limitaciones del caso previamente.

  9. Marcelo 07.31.06 / 09AM
    muy bueno el articulo, yo tengo una pregunta, quiero hacer un rewrite rule para un listado con paginacion: quiero que quede asi, ej.: /manuales/id34/php/ (pagina 1) /manuales/id34/php/1/ (tambien pagina 1) /manuales/id34/php/2/ (pagina 2) /manuales/id34/php/3/ (pagina 3) .... (etc.) Hay una forma de hacerlo? porque intente pero no me sale: RewriteRule manuales/(.*)/(.*)/(.*)/$ /manuales/listado.php?id=$1&tit=$2&pag=1 Con esa regla me sale error al poner sin el /1/ de paginacion, intente poner dos reglas, una debajo de la otra pero tampoco va. Existe algo para agregar o alguna forma de hacerlo? Ojala puedan ayudarme! GRacias!

  10. willy 08.04.06 / 06AM
    Saludos Marcelo. Disculpa por la demora en responder tu correo-e, estuve ocupado con unos proyectos. La regla que deberia funcionarte es la siguiente para dos tipos de URL La 1ra es para la página 1 sin número de paginado: Tu URL original: /manuales/listado.php?id=$1&tit=$2 La URL Amigable: /manuales/id34/php/ La Regla: Rewriterule ^manuales/(id[0-9]+)/(.*)/$ manuales/listado.php?id=$1&tit=$2 Donde (id[0-9]+) reemplaza a $1 y devuelve una cadena del tipo id1, id10 o id100 segun el ?id pasado por GET; y (.*) reemplaza al $2, ene ste caso el 'php' del &tit La 2da es para los pagiandos (sea 1,2,3 etc) Tu URL original: /manuales/listado.php?id=$1&tit=$2&pag=1 La URL Amigable: /manuales/id34/php/1/ La Regla: Rewriterule ^manuales/(id[0-9]+)/(.*)/([0-9]+)/$ manuales/listado.php?id=$1&tit=$2&pag=$3 Donde (id[0-9]+) reemplaza a $1 y devuelve una cadena del tipo id1, id10 o id100 segun el ?id pasado por GET; (.*) reemplaza al $2, en este caso el 'php' del &tit; y fianlmente ([0-9]+) reemplaza al $3 del &pag. Como verás solo son dos reglas: Rewriterule ^manuales/(id[0-9]+)/(.*)/$ manuales/listado.php?id=$1&tit=$2 Rewriterule ^manuales/(id[0-9]+)/(.*)/([0-9]+)/$ manuales/listado.php?id=$1&tit=$2&pag=$3 Si no te funcionan en ese orden, ponlas al inverso. Espero te haya sido de ayuda.

  11. www.floreame.net 08.17.06 / 12PM
    Optimizando una web de URL extensas a URL amigables con Apache y PHP... Este manual te explica cómo optimizar de manera sencilla una web dinámica hecha en PHP, cuyas URL’s pasadas a los enlaces contengan extensas variables pasadas mediante GET, a una web cuyas URL sean amigables (fáciles de recordar)....

  12. noticias.ncuentros.com 08.19.06 / 23PM
    Optimizando una web de URL extensas a URL amigables con Apache y PHP... En este manual Ud. aprederá cómo optimizar de manera sencilla una web dinámica hecha en PHP, cuyas URL’s pasadas a los enlaces contengan extensas variables pasadas mediante GET, a una web cuyas URL sean amigables (fáciles de recordar)....

  13. j0s 09.05.06 / 19PM
    bueno .. yo kisiera saber si funciona tambien en localhost .. pues estoy intentando .. de varias formas. pues e leido un monton de manuales de url amigables.. y ni uno me funca :S ..... toy usando el appserv ... graxx

  14. willy 09.08.06 / 05AM
    Saludos j0s. Si funciona en localhost. Tienes que ver que tengas bien configurado el mod_rewrite en el archivo de configuración de tu Apache.

  15. Optimizando una web con urls amigables con Apache y PHP 03.03.07 / 03AM
    [...] Este artículo fue publicado originalmente en willy.tiperu.com. [...]

  16. Alquiberia 05.01.08 / 14PM

    Tengo una duda. Me he fijado que en el ejemplo el máximo de variables es 9: Rewriterule ^(.)/(.),(.)/(.),(.)/(.),(.)/(.),(.*)/$ $1.php?$2=$3&$4=$5&$6=$7&$8=$9

    ¿Alguien ha probado a pasar 10 parámetros?

    Yo necesito pasar 10 variables, pero parece ser que no permite más de 9.

    Alguien tiene alguna sugerencia???

    Estoy aburrido de leer y buscar y la verdad es que no he encontrado absolutamente nada

    Gracias

    http://www.alquiberia.es


  17. hely 06.02.08 / 21PM

    Pregunta: como convertir una url asi: www.misitio.com/pagina.php?a=1

    en www.misitio.com/pagina.php?x=1 Osea: Cambiar el nombre de las variables

    probe esto pero no funciono: Rewriterule ^pagina\.php?a=(.+) pagina.php?x=$1


Tu comentario

Puedes usar HTML en tu comentario


(Requerido)

(Requerido)