RSS

Modrewrite Parte 1

Vie, Sep 21, 2007

Ajaxman, Apache, Manuales, Modrewrite

Recientemente tuve problemas con los permalinks, el modrewrite y el .htaccess, y poste una solución de este tema (con wordpress).

Sin embargo me surgió una duda, que pasa si ustedes desean aplicar modrewrite a un sitio web que no utilice wordpress como motor CMS, sin no construida directamente sobre php o alguna otra plataforma.

Resumiendo los pasos vamos a aprender a usar modrewrite lo mejor que podamos, por cierto voy a basarme en un articulo que hace tiempo publico IBM No apache que esta muy bueno, digamos que hare una especie de traduccion y tambien mejora de ese articulo.

Bueno ya vayamos al grano.

¿Que es MODREWRITE?

Modrewrite es una manera es reescribir las url en formas mas amigables tanto como para el usuario, como para que los buscadores nos indexen mejor.

Imaginemos el siguiente ejemplo, tenemos la siguiente direccion

www.miweb.com/index.php?articulo=12
www.miweb.com/index.php?articulo=11
www.miweb.com/index.php?articulo=15

Para todos seria difícil recordar cual articulo nos gusto ademas de que los buscadores como google quizá, pensarían que se trata de una sola pagina y no de 3 diferentes.

Sin duda se vería mejor de la siguiente manera.

www.miweb.com/articulo/12/javascript
www.miweb.com/articulo/11/xul
www.miweb.com/articulo/15/python

Bueno pues de esto trata modrewrite, ahora veamos como empezar a implementarlo.

En estos ejemplos usare Apache y Php y expresiones regulares

Si no saben expresiones regulares no se preocupen yo les ayudare.

Es recomendable que lo hagan lo puedan hacer con Vhost, pero no necesario

Empecemos

Primero hay que activar el modulo en el servidor apache

Esto se hace desde el httpd.conf el cual normalmente lo encontraremos en linux debe de estar en /etc/apache2/httpd.conf y en windows en C:\Archivos de programa\Apache Software Foundation\Apache2.2\conf\httpd.conf.

Buscamos la siguientes lineas
[source:java]
# Dynamic Shared Object (DSO) Support
#
# To be able to use the functionality of a module which was built as a DSO you
# have to place corresponding `LoadModule’ lines at this location so the
# directives contained in it are actually available _before_ they are used.
# Statically compiled modules (those listed by `httpd -l’) do not need
# to be loaded here.
#
# Example:
# LoadModule foo_module modules/mod_foo.so
#
……
[/source]

Hay una lista de modulos, para usarlos simplemente descomenten el modulo y reinicien apache

[source:java]
#LoadModule rewrite_module modules/mod_rewrite.so #esta asi
…….
……..
LoadModule rewrite_module modules/mod_rewrite.so #Quedaria asi
……
[/source]

Reiniciamos apache, y listo con esto ya tendremos cargado el modulo

Ahora hagamos una prueba hagamos el siguiente archivo ejemplo.php

[source:php]
var_dump($_GET);// nos permitira saber que variables recibimos por get

?>
[/source]

y lo guardamos en nuestro DocummentRoot, para ver que funciona vamos a nuestro navegador y teclamos al siguiente direccion

http://localhost/ejemplo.php?id=154, el Id es cualquiera

Y veremos algo asi.

[source:php]

array(1) { ["id"]=> string(3) “145″ }

[/source]

Ahora hacemos nuestras reglas de mod rewrite las cuales se agregan a nuestro httpd.conf dentro de la siguientes lineas

[source:java]

..



[/source]

y Agregamos lo siguiente

RewriteEngine On

RewriteRule /articulo/12/javascript/$ /ejemplo.php?Id=12
RewriteRule /articulo/11/xul/$ /ejemplo.php?Id=11
RewriteRule /articulo/15/python$ /ejemplo.php?Id=15

Veamos que significa la primer linea

RewriteEngine On, con esto le decimos que el modrewrite se ponga en modo activo, si no ponemos esta linea pues simplemente no podran usar modrewrite.

RewriteRule /articulo/12/javascript/$ /ejemplo.php?Id=12, Con esto decimos todo lo que recibas con la dirección
/articulo/12/javascript/ mandalo a /ejemplo.php?Id=12, y listo el signo de pesos, es para indicar el fin de la regla.

Sin embargo que ¿pasaría si tenemos 500 ó mas artículos? imagínense tener que copiar todo,

Entonces tenemos que recurrir a las expresiones regulares, por hoy no las tocaremos a fondo, simplemente las ocuparemos esporadicamente, veamos como.

Formemos la expresión regular.

  • Usaremos le numero para indicarle que id es el que necesita, el texto de momento no nos importa.
  • Hay que decirle que todo lo que reciba que sean números no guarde en una variable
  • Tambien hay que indicarle que pueden ser varios números

Para indicarle que pueden ser números hay que hacerlo de la siguiente forma [0-9], le decimos que pueden ser de cero a nueve, lo mismo aplica para las letras, solo que en ese caso hay que decirle si son mayusculas o minusculas, y ademas le especificamos que puede repetirse una o mas veces un numero de la siguiente forma [0-9]+ y por ultimo para guardarlo en una variable, lo encerramos entre paréntesis y quedaría así ([0-9]+)

Y por ultimo para pasárselo a nuestro link real lo pasamos mediante un signo de pesos seguido del numero de variable.
Entonces quedaría así.

RewriteRule /articulo/([a-9]+)/([a-zA-Z]+)/$ /ejemplo.php?Id=$1

La segunda variable que esta entre parentesis, no la ocupamos es simplemente para que nos quede mejor, de esta forma nos quedaría nuestro modrewrite de asi.

[source:java]
…..
RewriteEngine On

RewriteRule /articulo/([a-9]+)/([a-zA-Z]+)/$ /ejemplo.php?Id=$1

[/source]

Listo, ya estamos usando modrewrite, por cierto recuerden guardar el archivo httpd.conf y reiniciar el apache cada vez que hagan un cambio, cualquier duda déjenla en los comentarios con gusto las responderé.

This post was written by:

Ajaxman - who has written 576 posts on Ajaxman.


Contact the author

3 Comments For This Post

  1. Alquiberia Says:

    Muy buenas. Tengo una pequeña duda.
    Tengo implementado el mod_rewrite en mi web:

    http://www.alquiberia.es
    Pero tengo un problema cuando supero las 10 variables. Todo funciona perfectamente mientras no supere las 10 variables.
    Por ejemplo:
    Rewriterule ^([^/]+)-([^/]+)/([^/]+)-([^/]+)/([^/]+)-([^/]+)/([^/]+)-([^/]+)\.html$ index.php?$1=$2&$3=$4&$5=$6&$7=$8 [NC,L]

    Funciona perfectamente pero si supero las 9 variables falla y mezcla el valor de las variables.

    Alguna sugerencia???

    Gracias

  2. Ajaxman Says:

    @Alquiberia, apenas vi lo que me dijiste, y dejame te comento rapidamente, el codigo que me pusiste, es correcto ¿?, por que yo loveo incorrecto, ya que no deveria ser,

    index.php?valor1=valor2&valor3=valor4

    deberia ser

    index.php?varible1=varible2&varible3=variable4

    ya que si si te funciona o si lo usas asi, devbo de pensar en otras opciones saludos

  3. Alquiberia Says:

    Ajaxman, gracias por tu respuesta.

    El código que pongo funciona correctamente, siempre cuando no supere los 9 parámetros y sólo es usado en unas subsecciónes de la web (por necesidad), en el resto de secciones uso algo similar a esto:

    Rewriterule ^idioma-([^/]+)/seccion-([^/])\.html$ index.php?lang=$1&sec=$2 [NC,L]

    Te explico brevemente lo que necesito hacer :

    Para cambiar los enlaces dinámicos de la web uso preg_replace de esta forma:

    function _replace_rewrite($str) {
    $entra = array();$sale = array();

    //Lang y Seccion . 2 variables
    $entra[] = ‘¬index\.php\?lang=([a-z]+)&sec=([a-zA-Z0-9]+)¬’;
    $sale[] = ‘idioma-$1/seccion-$2.html’;

    //Lang. 1 variable
    $entra[] = ‘¬index\.php\?lang=([a-z]+)¬’;
    $sale[] = ‘idioma-$1.html’;

    $str = preg_replace($entra, $sale, $str);
    }

    Y funciona perfectamente, siempre y cuando el formato de entrada sea igual a los definidos en $entra[].

    Si entra: http://www.alquiberia.es/index.php?lang=es&sec=1
    , obtengo: http://www.alquiberia.es/idioma-es/seccion-1.html
    , después en htaccess lo redirecciono: Rewriterule ^idioma-([^/]+)/seccion-([^/])\.html$ index.php?lang=$1&sec=$2 [NC,L]

    Pero si entra http://www.alquiberia.es/index.php?sec=1&lang=es , el preg_replace no cumple su función.

    Imagínate esto pero con 14 ó 18 variables, a las que no les puedo dar un formato uniforme ya que se envían unas u otras dependiendo de varios factores.

    Mi intención era conseguir que se enviaran las variables que se recibieran de esta forma:

    //Lang y Seccion . 2 variables
    $entra[] = ‘¬index\.php\?([a-zA-Z0-9]+)=([a-zA-Z0-9]+)&([a-zA-Z0-9]+)=([a-zA-Z0-9]+)¬’;
    $sale[] = ‘$1-$2/$3-$4.html’;

    Rewriterule ^([^/]+)-([^/]+)/([^/]+)-([^/]+)\.html$ index.php?$1=$2&$3=$4 [NC,L]

    Esta es la idea básica, pero con un mínimo de 12 parametros y un máximo de 18.

    Por lo que he leido en la web de mod_rewrite: http://httpd.apache.org/docs/1.3/mod/mod_rewrite.html#RewriteRule

    # back-references $N to the RewriteRule pattern
    # back-references %N to the last matched RewriteCond pattern
    “Back-references are $N (N=0..9) identifiers which will be replaced by the contents of the Nth group of the matched Pattern.”

    Lo cierto es que después de una semana probando y buscando me doy por vencido, he probado con RewriteCond y RewriteMap y más o menos conseguí enviar 14 parametros pero es un trabajo muy tedioso y no es rentable, he optado por otra opción más cómoda para mi aunque un poco menos efectiva.

    Gracias por todo.

    Ya te digo, que lote describí ;-)

Leave a Reply