Síganos en Facebook
Volver al Blog de Emenia

Cómo crear URLS amigables con .htaccess

Escrito el por

¿Qué es una URL amigable? Lo mejor es un ejemplo. Esto NO es una URL amigable:

htaccess1
En cambio esta SI es una URL amigable:
htaccess2

Su propio nombre lo indica: las URL amigables son más fáciles de usar y de recordar por los usuarios y también se dice (y hay quien dice que no) que son mejores para el posicionamiento en buscadores. Además describen mucho mejor los enlaces dentro de una página web y añade un mayor nivel de profesionalidad a nuestras webs.

De todas formas, cuando hemos creado una página dinámica en PHP lo normal es que tengamos URL no amigables. ¿Cómo las convertimos en amigables de manera automática? Una manera de hacerlo es con un archivo .htaccess y gracias a Apache y su mod_rewrite.

Veamos la teoría: mod_rewrite es un módulo de Apache que permite manipular en el servidor las URLs solicitadas. Es decir, cuando llega al servidor la solicitud de una URL, esta se comprueba con respecto a una serie de reglas creadas con Expresiones Regulares creadas para detectar un patrón determinado. Si se encuentra ese patrón en el URL y se cumple la condición impuesta por la Expresión Regular se sustituye el patrón por una cadena de texto o por una acción determinada.

htaccess3

IMPORTANTE: Para que todo esto funcione tiene que estar activado el módulo mod_rewrite en nuestro servidor Apache. Podemos saber si lo está simplemente con:

1
<?php phpinfo(); ?>

Y de entre toda la información recibida si el módulo está activado tendremos:
mod_rewrite

Lo más normal es que esté activado. Sino fuera así quizás tendríamos que hablar con nuestro proveedor de hosting.

Una vez sabemos que mod_rewrite está activado lo que necesitamos es un archivo .htaccess ¿Qué es un archivo .htaccess? Es un fichero de configuración utilizado por los servidores web Apache. Son archivos de texto.

¿Qué vamos a escribir en el archivo .htaccess? Como decíamos antes, una serie de Expresiones Regulares para interpretar el URL entrante y crear un URL saliente interpretable por nuestro código. Si no sabéis nada sobre Expresiones Regulares (o Regular Expressions en Inglés) es importante que leais algo sobre las mismas antes de seguir. Con una simple búsqueda en Google podréis encontrar gran cantidad de tutoriales. Si sabéis inglés, este tutorial de themeforest es muy bueno. También podéis bajaros esta hoja de referencia de Expresiones Regulares (en inglés)

Bueno, vamos a pasar a la acción. Os aconsejo que lo hagáis también vosotros improvisando casos distintos para poderlo comprender mejor. Vamos a empezar por un ejemplo sencillo: Vamos a crear dos archivos, uno index.php y otro clientes.php

index.php tendrá únicamente un enlace a clientes.php, para simplificarlo todo un poco.

1
2
3
4
5
6
7
8
9
10
11
12
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="es" xml:lang="es">
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
	<title>Ejemplo de URL amigable</title>
</head>
<body>
  <h1>Ahora estás en index.php</h1>
  <a href="clientes/juan">Juan</a>
</body>
</html>

Como podéis ver el enlace es ya una URL amigable. Sin embargo al hacer click sobre el enlace necesitamos interpretar esa URL que llega al servidor para que este sepa qué hacer. Creamos un archivo de texto, lo grabamos como .htaccess y escribimos en él:

1
2
3
4
5
6
7
# Activar RewriteEngine
RewriteEngine on
 
# Reescribir la URL solicitada por el usuario
#   Entrada:  clientes/NOMBRE/
#   Salida: clientes.php?id=NOMBRE
RewriteRule ^clientes/(\w+)/?$ clientes.php?id=$1

Vamos a ver línea a línea. En primer lugar tenemos que activar la re-escritura de la URL, para lo cual hay que activar RewriteEngine. A continuación establecemos una Regla de Re-escritura (RewriteRule) para gestionar la página clientes.php. Como véis, estamos re-escribiendo la URL amigable clientes/juan al formato normal clients.php?id=’juan’
En esta regla de re-escritura hay dos partes. Por un lado ^clientes/(\w+)/?$ que es una expresión regular que indica:
htaccess4
Ahora vamos con la segunda parte. En la segunda parte tenemos la expresión que sustituirá a la primera parte:
htaccess5

Ahora vamos a ver el archivo clientes.php:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
// Obtenemos el nombre del usuario desde la URL
$id = $_GET['id'];
?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="es" xml:lang="es">
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
	<title>Ejemplo de URL amigable</title>
</head>
<body>
  <h1>Ahora estás en clientes.php</h1>
  <p>Nombre del cliente: <?php echo $id; ?></p>
</body>
</html>

Haced la prueba y veréis cómo funciona perfectamente la URL amigable. Para complicar más las cosas se pueden incluir banderas al final que cada expresión. Imaginaros por ejemplo que hubiera posibles alternativas para reescribir una URL amigable, pero queremos que una vez encuentre la primera se detenga ahí y no siga contrastándose con el resto de Expresiones Regulares. Entonces la bandera a añadir sería [L]:

1
2
RewriteRule ^([a-zA-Z0-9-]*)/([0-9]+)\-([a-zA-Z0-9-]*)\.html(.*)$ product.php?id_product=$2$4 [L]
RewriteRule ^([0-9]+)\-([a-zA-Z0-9-]*)\.html(.*)$ product.php?id_product=$1$3 [L]

Tenéis todas las banderas en esta hoja de ayuda rápida de mod_rewrite.

Por último, decir que es aconsejable añadir unas pocas líneas más a nuestro código. Lo voy a hacer aprovechando para crear un nuevo ejemplo. Supongamos un caso como este:
htaccess6
El archivo .htaccess que crearíamos sería:

1
2
3
4
5
6
7
8
9
10
11
12
<IfModule mod_rewrite.c>
# Activar RewriteEngine
RewriteEngine on
RewriteBase /
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
 
# Reescribir la URL solicitada por el usuario
#   Entrada:  ID-NOMBRE
#   Salida: pruducto.php?id=ID
RewriteRule ^([0-9]+)\-([a-zA-Z0-9-]*)$ producto.php?id=$1
</IfModule>

Hemos añadido un condicional:

1
2
<IfModule mod_rewrite.c>
</IfModule>

para comprobar que está activado el módulo antes de hacer nada. Luego hemos añadido “RewriteBase /” que indica que el directorio base es el raíz. Si fuera por ejemplo una carpeta llamada “base” haríamos “RewriteBase /base”.
Además hemos añadido dos líneas que lo que hacen es restringir la re-escritura sólo a rutas que no existan previamente. Es decir, que no valdría por ejemplo para ejemplo.com/imagenes/logo.png. La primera línea previene los directorios que ya existan con la bandera !-d y la segunda hace que se ignoren ficheros que ya existan con la bandera !-f.

Luego, en la regla de reescritura, tenemos una entrada compuesta por números, luego va un guión (/-) y luego una cadena que puede incluir letras en mayúsculas, en minúsculas, números y guiones (por lo que 34-lampara-verde cumpliría). La salida que ya conoce nuestro código PHP (aunque esto está oculto al usuario) es producto.php?id=$1, siendo $1 el valor que hemos atrapado entre los dos primeros paréntesis (en este caso, 34). Si observáis tenemos también atrapado un segundo grupo que es ([a-zA-Z0-9-]*) y que lo podríamos recuperar con $2, pero en este caso no nos sirve.

Esto es sólo el comienzo, pero toda la base está ahí. Otra manera alternativa de conseguir URL amigables es combinar un archivo .htaccess con PHP, pero eso sería materia de otro artículo. Algunas de las lecturas recomendadas a continuación sí indican cómo hacerlo.

Lecturas Recomendadas

baluart.net: Ofrece una función muy interesante para transformar el título de una noticia (por ejemplo) y transformarlo (cambiando las letras con tildes, eñes, etc) para conseguir una frase asequible a los buscadores y navegadores – Urls Amigables con PHP
corz.org: more .htaccess tips and tricks..
nettutplus.com: Using htaccess Files for Pretty URLS
nettutplus.com: A Deeper Look at mod_rewrite for Apache
stewparkin.com: Apache Re-Writes in .htaccess
Source Rally: Make pretty URLs with PHP and mod_rewrite
AddedBytes: URL Rewriting for Beginners
webm.ag: How To Make Dynamically Generated SEO-Friendly URLs Using PHP And .htaccess
noupe: 10+ Mod_Rewrite Rules You Should Know

Sigue a Juan en Twitter, en Google+, o suscríbete al RSS Feed de Emenia para estar al día de nuestros artículos.

Artículos relacionados

75 Comentarios a Cómo crear URLS amigables con .htaccess

  1. Zoltran dice:

    Lo mismo puede hacerse con el PATH_INFO desde php sin usar rewrite
    Saludos.

  2. jack dice:

    e no me sale nada–
    active el mod_rewrite y segui exactamente como dicen pero nada llamo a la pagina y me sale..
    ——
    ¡Objeto no encontrado!
    El enlace requerido no ha sido localizado en este servidor. Si usted proporcionó el enlace de manera manual le solicitamos que por favor revise los datos e intentelo de nuevo.

    Por favor contacte con el webmaster en caso de que usted crea que existe un error en el servidor.

    Error 404

    localhost
    02/06/10 21:53:21
    Apache/2.2.11 (Win32) PHP/5.2.8

  3. Ariel Crippa dice:

    Hola: Estoy haciendo el ejemplo que muestras y cuando hago clic en Juan me lleva a clientes.php y me da NOT FOUND.
    Segun mi hosting tengo el mod_rewrite activado.
    El archivo .htaccess lo copio tal cual lo tenes vos y lo coloqué dentro del directorio public_html, que es el directorio donde tengo index.php y clientes.php.
    Tambien probe de ponerlo un nivel más arriba de public_html y nada.
    Podrías explicarme??

  4. En mi archivo .htaccess aparece lo siguiente:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    ------------------------
    # BEGIN WordPress
    
    RewriteEngine On
    RewriteBase /
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.php [L]
     
    # END WordPress
    ------------------------

    El problema es que también tengo una subcarpeta /puebas/ protegida con contraseña.
    En este caso, me da la impresión de que la condición “!-f” interpreta que el archivo no existe y me reescribe la URL, cuando realmente no es que no exista, sino que no se puede acceder sin introducir la contraseña.
    ¿Se te ocurre alguna manera de hacer que la regla no aplique a esa carpeta?
    He probado añadiendo “RewriteCond %{REQUEST_FILENAME} !.*/pruebas/.*” pero no funciona.

  5. gonself dice:

    Muy buen tutorial, muchas gracias! no solo funciona si no que aprendees a trastear tu. gracias.

  6. term dice:

    Excelente entrada, explicado desde el principio y bastante claro para empezar.
    Un saludo

  7. Martin dice:

    Hola, estoy intentando montar url amigables en una web que tiene base de datos y php. Lo que necesito es que dentro de uan carpeta en este caso llamada pais, las url sean amigables. Tengo un index.php, y otra condado.php y este es el .hteccess que intentgo poner pero no funciona

    1
    2
    3
    
    RewriteEngine On
    Options FollowSymLinks
    RewriteRule ^pais/condado/(\w+)/?$ pais/condado.php?id=$1

    Deberia quedar:

    1
    
    http://www.misitio.com/pais/condado/

    ¿como puedo comprobar si funciona la url amigable?

    ¿Puedo poenr el archivo .htacess solo en una carpeta para que actùe solo sobre esas url?
    En que puede fallar el código que pongo.
    Desconozco totalmente la programación y me resulta dificil entender lo que representa cada paso.

    Como verás estoy muy verde en esto y he intentado copiar tu código pero siempre me sale error.

  8. Javier dice:

    Hola estimado, como sería el htaccess si tengo el sgte link?:

    index.php:

    1
    
    <a href="detalles.php?cat=1&amp;cod=100" rel="nofollow">detalles</a>

    Ya intenté pero no hay caso…

    al archivo index.php y detalles.php lo tengo todo en la misma carpeta /public_html/

    Muchas gracias de antemano!.

  9. luis miguel dice:

    lo unico que quiero es como se crea el archivo mas no su contenido, please ayudenme.

  10. edwin dice:

    buenas. vi su tutorial de como crear url amigables. implemente para un proyecto de galerias de imagenes con bd. me muestra bien, pero cuando regreso al index.html no me reconoce y me muestra la pagina de la galeria de imagenes pero sin las fotos.

    este es mi codigo.

    1
    2
    3
    
    RewriteEngine On
     
    RewriteRule ^([a-zA-Z0-9-]*)\.html(.*)$ detalles.php?&amp;url_categoria=$1

    me pueden ayudar en ello ?.

    saludos.

    1
    
    RewriteRule ^our_pieces.html$ our_pieces.php [L]
  11. Javine dice:

    Algo que no tengo todavia muy claro, es que con solo modificar el archivo .htaccess no es suficiente, sino que en cada página php tendría que modificar los links internos para que se redireccionen a las nuevas urls?

    • Juan Diaz-Bustamante dice:

      Efectivamente Javine. En el redireccionamiento del archivo .htaccess pones el link que se recibe y luego, digámoslo así, su traducción al formato que PHP entiende.

  12. Hola Juan, seguí tu tutorial y me funcionó muy bien al crear la url amigable, en la barra de direcciones aparece lo que necesito (marcas/carros)pero al cargar ésta página se pierde toda la parte gráfica que está definida en los estilos css y sólo aparecen textos sin gráficos ni los logotipos de las marcas de autos que deberían estar, tambien desaparece la animación flash superior.

    Al regresar a index.php me da error 404 url no encontrada.

    El código de mi htacces es el siguiente:

    Options +FollowSymLinks
    RewriteEngine on
    RewriteCond %{HTTP_HOST} ^www.ofertacarro.com$
    RewriteRule ^/?$ “http\:\/\/ofertacarro\.com” [R=301,L]
    RewriteRule ^marcas/(\w+)/?$ buscar-marca.php?tip=$1

    Te agradecería una ayuda.

    Gracias de antemano

  13. Yoanofthecourth dice:

    Hola a todos,

    Primero de todo felicidades por el artículo llevo días buscando por internet y hasta que no he topado con este blog no he conseguido comprender como funcionan las url amigables con htaccess.

    Ara tengo una duda a ver si alguien me la puede resolver. Según el ejemplo y si no lo entiendo mal, por cada página que quiera que tenga una url amigable tengo que hace una entrada en el htaccess. El problema es que mi página web tiene multiples páginas y eso es un auténtico fastidio. Alguien me puede decir si existe alguna forma de automatizar más este proceso?

    Gracias y saludos,

    • Juan Diaz-Bustamante dice:

      Depende de la estructura de las url de tus páginas. Como verás en el artículo, puedes establecer un patrón que englobe todas tus paginas.

  14. Xavi dice:

    Dios existe!! Gracias por tan grande aportación.
    LLevo dos dias intentando hacer funcionar un .htaccess para activar el mod_rewrite? y me era imposible.
    He aprendido a hacerlo y me funciona.
    Ahora mismo me dedico a crear personificados.
    Gracias gracias

  15. Fernando dice:

    Me parece excelente este turorial.
    Solo una consulta si tuviera una url asi como esta

    1
    
    https://www.miweb.com/index.php?pag=nombredepagina&o_aoID=8073-2010

    Como sería la configuración de mi htaccess?
    Gracias de Antemano, por la ayuda.
    Saludos,

    • Juan Diaz-Bustamante dice:

      Hola Fernando,

      Cuando tienes dos variables puedes probar a hacer algo así:

      1
      
      RewriteRule ^([a-zA-Z0-9-]*)/([a-zA-Z0-9-]*)/?$ index.php?pag=$1&a_aoID=$2 [L]

      Dentro del primer paréntesis va la expresión regular para la primera variable y en el segundo para la segunda, de tal manera que la url te quedara miweb.com/nombredelapagina/8073-2010

      No sé si es así como lo quieres.

  16. Fernando dice:

    La verdad no se que estoy haciendo mal… No me esta funcionando.
    Habilite el modulo en el apache estoy usando el xampp, baje unos archivos para ver si me esta funcionando el modulo mod_rewrite y efectivamente me esta funcionando.
    Lo cree para la el ejemplo que puse arriba y nada.
    Hice otra regla para otra página e igual no me funciona /cry.
    Página siguiente:

    1
    2
    3
    4
    5
    6
    
    http://localhost/nueva.pagina.prueba/subcategoria.php?cid=16&amp;sid=45
    RewriteEngine on
    RewriteBase /nueva.pagina.prueba
    RewriteCond %{SCRIPT_FILENAME} !-d
    RewriteCond %{SCRIPT_FILENAME} !-f
    RewriteRule ^([a-zA-Z]+)/([a-zA-Z0-9]+).htm$ /subcategoria.php?cid=$1&amp;sid=$2 [L,NC]

    Que entonces lo que estoy haciendo mal?
    Gracias.

    • Juan Diaz-Bustamante dice:

      Hola no tengo xampp, pero mira lo que dice este artículo sobre el uso de XAMPP mod_rewrite y las URL amigables (está en inglés pero es muy claro). No sé si será ese el problema…

      • Fernando dice:

        Si todos esos pasos ya los realice, probe que funciona con unos archivos que baje de internet para problar la funcionalidad del mod_rewrite y me funciono.
        Este ejemplo era haciendo click en un link, ok pero si yo quiero que desde que me cargue la página, se vea ocultando las variables, no me esta funcionando.
        Lo otro es que en el menu el link esta como:

        1
        
        http://localhost/nueva.pagina.prueba/subcategoria.php?cid=16&amp;sid=45

        debe estar asi? o en el menu yo debo de cambiar el url?
        Porque estuve leyendo en varios blog que suspuestamente con agregar el htaccess, no hay que hacer ningun cambio en la aplicación.
        Por último la regla que definí en la parte de arriba es la correcta?

        Muchas Gracias por Responder.
        La verdad ha sido de mucha ayuda.

        • Juan Diaz-Bustamante dice:

          Como es el enlace que pones para que vaya a ese link? porque los números 16 y 45 (siguiendo con tu ejemplo) tienen que aparecer y la primera parte sólo incluye letras y no números ([a-zA-Z]+) mientras que dices que cid=16. El enlace parece quedar un poco raro, ya que pones que sea algo así como cid/sid.htm sin más?

          • Fernando dice:

            Ah ok ya primera parte esta mal , deberia de agregarle los números, es que no estoy muy práctico…
            Lo que quiero en realidad es ocultar mi url real.
            En el menú de mi aplicación no he realizado ningún cambio en los link, van igual por ejemplo: subcategoria.php?cid=16&sid=45
            donde el cid es el código de mi categoria y el sid es el de mi subcategoría.
            El htacess es solo como lo puse arriba me hace falta algo mas?
            es problema es que ya coloque el archivo htacess y el url me sigue saliendo:subcategoria.php?cid=16&sid=45
            no cambia nada.

  17. luis fernando romero del castillo dice:

    buenas tardes jack, he realizado todo deacuerdo a tu explicación pero no sale nada.
    me explico
    1. archivo .htaccess

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    # Activar RewriteEngine
    RewriteEngine on
    RewriteBase /
    RewriteCond %{SCRIPT_FILENAME} !-d
    RewriteCond %{SCRIPT_FILENAME} !-f
     
    # Reescribir la URL solicitada por el usuario
    #   Entrada:  id
    #   Salida: negocio.php?id=id
    RewriteRule ^([0-9]+)\-([a-zA-Z0-9-]*)$ negocio.php?id=$1

    lo coloque tal cual como tu dices.
    en index.php tengo lo siguiente

    1
    
    <href="http://localhost/barranquillaofertasnegocio.php?id="> lo que se convierte en http://localhost/barranquillaofertas/negocio.php?id=1.

    pero este enlace me sigue saliendo igual y cuando pincho en el enlace el resultado es igual
    muchas gracias por tu ayuda.

  18. Daniela dice:

    Hola, vengo siempre a tu blog ya que encuentro cosas realmente interesantes y muy bien explicadas, he puesto en practica más de un tutorial sobre wordpress y siempre con éxito. Gracias por eso!
    Bueno, esto te lo debia, ahora mi duda: Si yo tuviera una variable de url del tipo…

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    if(isset($_GET['page']) &amp;&amp; $_GET['page']=='empresa'){
    // include empresa
    include('include/in-empresa.php');
    //Si no , se comprueba el valor nuevamente
    } elseif(isset($_GET['page']) &amp;&amp; $_GET['page']=='contacto'){
    // include contacto
    include('include/in-contacto.php');
    // En cualquier otro caso , mostramos el home
    } else {
    include('include/in-home.php');
    }

    …para llamar a los distintos archivos, tendría un único menú (en otro include) que se vería asi:

    1
    2
    3
    
    <a href="index.php?page=home" rel="nofollow"> Inicio</a>
    <a href="index.php?page=empresa" rel="nofollow"> Empresa</a>
    <a href="index.php?page=contacto" rel="nofollow"> Contacto</a>

    Mi pregunta es, cómo hago para que las urls se vean: dominio.algo/empresa/ sin tener que cambiar los links internos, ya probé con htacces y no lo consigo, incluso probé algunos generadores htacces on line y tampoco resulta. Será que simplemente no se puede.
    Gracias por tu tiempo.

    • Juan Diaz-Bustamante dice:

      Gracias Daniela por tus comentarios.

      Ten en cuenta que si quieres que las urls se vean dominio.algo/empresa/ los links tienen que ser así:

      1
      
      <a href="/empresa/" rel="nofollow"> Empresa</a>

      o también

      1
      
      <a href="dominio.es/empresa" rel="nofollow"> Empresa</a>

      Y luego con htaccess haces la conversión a index.php?page=home para que así lo entienda tu código de php.

      • Hector dice:

        Excelente. Mis url son amigables. Tengo una consulta,porque a partir de eso es que cuando quiero realizar un sitemap en forma automatica me repite cada carpeta como si fuera la base. por ejemplo alimentiaweb.com/acerca-de-alimentia tambien pone alimentiaweb.com/clientes/acerca-de-alimentia
        Cual seria el error?
        Gracias

  19. Hector dice:

    Excelente tus comentarios. Solo deseaba consultarte si en mi portal al hacer click en “ver mas” de una empresa, redirecciona a $emp = “empresa_detalle.php?id=”.$tr['id'] donde id es un numero y la url seria (en el caso de una empresa determinada) empresa_detalle.php?id=124 y deseo aparezca en vez de 124 el nombre de la empresa en este caso EFITECNICA GROUP que debo hacer?

    • Juan Diaz-Bustamante dice:

      Hola Hector, gracias por tus comentarios.

      Si el id va a ser siempre 124 para este caso concreto simplemente sería hacer algo así:

      1
      
      RewriteRule ^efitecnica_group[/]*$ empresa_detalle.php?id=124 [QSA,L,E]

      Si el número del id varía no tienes más remedio que incluirlo en la url.

  20. Seiya dice:

    Muy buenas Juan,
    estoy intentando utilizar un htaccess para mi web, pero no me funciona con las secciones.
    No me da problema en la home, pero cuando intento escribir la url de una sección me da un 404.
    Es más sencillo que el tuyo y puede que esté mal porque le falten cosas (y yo no lo sepa)
    El código es este:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    # Activar RewriteEngine
    RewriteEngine on
    RewriteBase /
    RewriteCond %{SCRIPT_FILENAME} !-d
    RewriteCond %{SCRIPT_FILENAME} !-f
     
    # Reescribir la URL solicitada por el usuario
    #   Entrada:  SECCION
    #   Salida: index.php?seccion=SECCION
    RewriteRule ^(\w+)/?$ index.php?seccion=$1

    Una ayudita :’(

  21. Jose dice:

    Hola Juan. Buenísimo el post. Tengo una duda. Cuando haces esto tanto la url antigua como la nueva siguen activas. Es decir que por ejemplo google detectaría contenido duplicado. Se debería por tanto según he leído por ahí hacer un redireccionamiento desde la URL antigua hacia la nueva. Lo estoy intentando hacer pero no me sale. Lo puedo hacer desde php pero preferiría hacerlo con una regla en htaccess. ¿Me podrías por favor echar una mano?.

    1
    2
    3
    4
    5
    6
    7
    
    Options +FollowSymLinks
    RewriteEngine on
    RewriteBase /
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^inmobiliarias-(.*)/?$ inmobiliarias-$1.php [L]
    RewriteRule ^inmobiliarias-(.+)\.php$ inmobiliarias-%1 [L,R=301] esta última línea es la que no me sale (no me funciona)

    Gracias de antemano

    • Juan Diaz-Bustamante dice:

      Gracias Jose,

      ¿Puedes poner un ejemplo del enlace que usas? Ten en cuenta que la parte de la izquierda es la URL amigable y la de la derecha la real.

      • Jose dice:

        Por supuesto:

        1
        
        http://www.miweb.com/inmobiliarias-espana.php    http://www.miweb.com/inmobiliarias-espana

        Gracias

        • Jose dice:

          Es decir, la real es la acabada en php como es lógico y la otra la amigable. Muchas gracias por responder.

          • Juan Diaz-Bustamante dice:

            Hola Jose,

            Lo tienes al revés en el htaccess. Ten en cuenta que a la izquierda va la amigable y a la derecha la real. La del .php tiene que ir a la derecha

          • Jose dice:

            ¿Pero cual de las dos tengo al revés?. Esta me acepta la ulr sin .php así que va bien

            1
            
            RewriteRule ^inmobiliarias-(.*)/?$ inmobiliarias-$1.php [L]

            y la otra es la que redirecciona y no lo hace bien. ¿Serías tan amable de poner el código como dices?. Gracias y perdona por ser tan torpe.

          • Juan Diaz-Bustamante dice:

            Perdona Jose por no ser claro. A la izquierda va la amigable (la que no tiene .php) a la derecha va la real (la que tiene .php que es la que entiende tu código). La que no te funciona es la que tienes al revés.

            Como la amigable tu código no la entiende por eso la cambias con el htaccess a la que sí entiende.

          • Jose dice:

            Ok. ahora entiendo lo que querías decir. Perdona si no he sabido explicarme. El código me va bien, lo que pasa es que con la línea que dices que tengo al revés no quiero hacer lo mismo que antes. Eso ya lo tengo con la primera línea. Es decir si meto tanto la URL amigable como la que acaba en .php ambas me llevan al mismo sitio. Lo que pretendía con la segunda regla era hacer un redireccionamiento. Es por eso por lo que lo tenía al revés, justamente para decirle que si la url acaba en .php redireccione hacia la amigable. Con otras URLS dinámicas si que me va, pero no entiendo porqué se me resiste esta. ¿alguna idea?.
            Gracias

          • Juan Diaz-Bustamante dice:

            Ah ya te entiendo. Para hacer un redireccionamiento tendrías que hacer así:

            1
            
            redirect 301 /inmobiliarias.php http://www.tudominio.es/inmobiliarias
          • Jose dice:

            Si pero así sería si la dirección fuese fija como inmobiliarias.php pero no como inmobiliarias-(.*).php
            Acabo de dar con una posible solución que hace lo que quiero, pero es curioso que funciona bien con casi todas las provincias menos con Barcelona, jeh jeh que raro. Este es el código completo:

            1
            2
            3
            4
            5
            6
            7
            
            RewriteEngine on
            RewriteBase /
            RewriteCond %{REQUEST_FILENAME} !-f
            RewriteCond %{REQUEST_FILENAME} !-d
            RewriteRule ^inmobiliarias-(.*)/?$ inmobiliarias-$1.php [L]
            RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /inmobiliarias(.+)\.php\ HTTP/
            RewriteRule ^inmobiliarias-(.*)\.php$ /inmobiliarias%1? [L,R=301]
  22. Lucho dice:

    Hola que tal? estoy aprendiendo sobre mvc y urls amigables y estoy montando un pequeño sistema de gestion de socios para que funcione como intranet para el club de mi barrio que aparte como ayuda a mi club me sirve para aprender un poco, bueno basta de vueltas, lo que pasa es que quiero hacer que se vean urls amigables y no se como encarar, tengo activado mod_rewrite pero no entiendo bien el tema de la expresiones, por ejemplo yo tengo el formulario de ingreso y al ingresar a la pagina principal me sale la siguiente url

    1
    
    http://localhost/gestionSocios/?controlador=Login&amp;accion=iniciarSesion

    me gustaria que esto se vea mas amigable y la verdad no se como encararlo si me dan una mano les agradeceria, saludos cordiales.

  23. Pablo dice:

    Hola Jose, buenas tardes
    Estoy con el tema de url amigables, he buscado por todos lados pero no logro hacer que funcione, te paso una ejemplo de mi link :

    1
    
    index.php?action=masinfo&amp;code=57&amp;r=Violadores del Verso en Buenos Aires

    Necesitaria saber como crear el htaccess, el codigo php puse el siguiente pero tampoco funciona :

    1
    
    <a href='masinfo/{$row[id]}/{$row[nombre]}' rel="nofollow">

    Me puedes ayudar con esto??

    Gracias

  24. Rosa dice:

    Hola juan, mira mi problema es que mediante una variable en un embed recojo una url pero si coloco esa url en la barra hace descarga directa desde mi host de pruevas podria denegar cualquier descarga desde el .htaccess pero que en el embed reproduciera el archivo…gracias.

  25. martin dice:

    Hola, recien me estoy intruyendo en esto del trabajo con .htaccess… me gustaria saber si me puedes hechar luz a lo siguiente:

    Tengo una web con las siguientes urls:

    1
    2
    
    http://www.pagina.com/productos/nombre-del-producto/all/9/0/0/
    http://www.pagina.com/producto/10/0/66/nombre-del-producto.html

    La cuestion es que me gustaria cambiar por lo siguiente:

    1
    2
    
    http://www.pagina.com/productos/nombre-del-producto/
    http://www.pagina.com/producto/nombre-del-producto.html

    Como deberia escribir esto dentro del .htacess
    Hay alguna forma de probar esto antes… por ejemplo trabajando de forma loca.
    Muchas gracias.
    Martin.

    • Juan Díaz-Bustamante dice:

      Hola Martin,

      Si no tienes ningún parámetro que pasar en el GET puedes hacer un simple redireccionamiento 301 del tipo:

      1
      
      redirect 301 /productos/nombre-del-producto/all/9/0/0/ http://www.pagina.com/productos/nombre-del-producto/

      Si los números de la primera URL son parámetros necesarios, tienen que aparecer de alguna manera en la segunda url para podérselos pasar a tu código.

  26. Jask dice:

    Muy muy muy buen artículo. Me aclaró un montón de dudas y aprendí muchas otras cosas que desconocía. También está explicado de lujo, sin abarrotar de tecnisísmos, para que la gente lo entienda mejor. Mis felicitaciones.

    Por otro lado tengo una pequeña duda, a ver si entre varios podemos resolverla.

    Tengo una web con la siguiente url: http://www.web.com/?pagename=tus-stars&ficha=id

    El .htacces que he creado (solo pongo la parte que he creado yo, lo demás viene de WordPress) es la siguiente:

    1
    
    RewriteRule ^tus-stars/([0-9]+) pagename=tus-stars&amp;ficha=$1       [L]

    Pero no me funciona, alguna sugerencia al respecto ?

    Gracias !!

  27. Gabriel dice:

    Hola a todos… observen la url q bota mi web:

    1
    
    "http://deportivotachira.com.ve/2012/full.php?subaction=showfull&amp;id=1317910374&amp;archive=&amp;start_from=&amp;ucat=1"

    mi pregunta es ¿como debo modificar el htacces.. quiero q me quede algo asi?

    1
    
    "http://deportivotachira.com.ve/2012/titulo-de-mi-noticia"

    otra cosa.. este es mi htacces:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    
    RewriteEngine on
     
    RewriteCond %{HTTP_HOST} ^deportivotachira.com.ve$ [OR]
    RewriteCond %{HTTP_HOST} ^deportivotachira.com.ve$
    RewriteRule ^/?$ "http\:\/\/www\.deportivotachira\.com.ve" [R=301,L]
     
    RewriteCond %{HTTP_HOST} ^deportivotachira.net$ [OR]
    RewriteCond %{HTTP_HOST} ^www.deportivotachira.net$
    RewriteRule ^/?$ "http\:\/\/www\.deportivotachira\.com.ve" [R=301,L]
     
    RewriteCond %{HTTP_HOST} ^deportivotachira.com.ve$ [OR]
    RewriteCond %{HTTP_HOST} ^www.deportivotachira.com.ve$
    RewriteRule ^/?$ "http\:\/\/deportivotachira\.com.ve\/index\.php" [R=301,L]

    AYUDA POR FAVORRR– se los agradecere mil veces mil…
    saluds

    • Juan Díaz-Bustamante dice:

      Hola Gabriel,

      He eliminado tu enlace con la info de tu configuración de php porque puede ser inseguro para ti.

      Un URL como el que quieres le vas a tener que hacer por PHP. Mediante htaccess tienes que pasar los valores de las dos variables (siempre y cuando estas sean necesarias), que son “subaction” e “id”, tal y como ves en los ejemplos del artículo.

  28. Pingback: URL’S AMIGABLES CON .HTACCESS

  29. Jairo dice:

    Buenas tardes, he utilizado tu tutorial para crear urls amigables en una web que estoy montando en php.
    Funciona perfectamente, pero me surge un problema.
    Si yo mismo escribo un enlace del tipo: http://miweb.com/no-existe, en lugar de mandarme al index.php como hacía antes, me salen los mensajes de Warning:no such file etc.

    Mi pregunta es, en el caso de que no exista la página en un directorio determinado, en este caso miweb.com/pages/x, ¿se puede mandar al usuario al index.php o a la tipica página de error o habría que hacerlo en php en pages.php?
    El contenido de mi pages.php (el que saca una página u otra) es:

  30. Jairo dice:
    1
    2
    3
    4
    5
    
    if (!isset($_GET['page'])) {
        include("pages/home.php");
    } else {
        include("pages/".$_GET['page'].".php");
    }

    Le he añadido

    1
    
     error_reporting(0);

    para que no salgan los warning, pero lo que me interesa es que cuando salga un Warning, me envíe a una página determinada o bien redirija a 404.

    Gracias

  31. David dice:

    Juan, genial aporte una vez más!

    Aun así me ha surgido un problema con mi .htaccess. Tengo un directorio en mi web llamado “rss” (cuyo fichero inicial es un index.php) y, con el siguiente codigo .htaccess, no me deja acceder. Debe ser porque supone que es uno de los menús de la web y no un directorio.

    1
    2
    3
    4
    
    Options +FollowSymlinks
    RewriteEngine On
     
    RewriteRule ^(\w+)/?$ index.php?menu=$1

    Además, con .htaccess, habia protegido el directorio “rss” con contraseña.

    1
    2
    3
    4
    
    AuthName "rss"
    AuthUserFile ".htpasswd"
    AuthType Basic
    require valid-user

    ¿Habría alguna manera de poder tener ambos códigos en el mismo .htaccess y que no entrasen en conflicto? Quizá con alguna condición previa… no sé muy bien.

    Espero vuestra ayuda! Saludos!!

  32. Pablo dice:

    Gracias maestro!!! Sos un genio la verdad… no solo me salio esto en 15 minutos, si no que aprendí bastante de como manejar los .htaccess, me sirvió completamente para lo que lo necesita…
    Mil gracias!

    Saludos desde Argentina ^^

  33. angel vargas dice:

    que tal, yo tengo una duda al usar dos o mas reglas
    tengo lo siguiente:

    1
    2
    3
    4
    5
    6
    7
    
    Options +FollowSymLinks
    RewriteEngine on
     
    RewriteCond %{REQUEST_FILENAME} !-f
     RewriteCond %{REQUEST_FILENAME} !-d
     RewriteRule ^(.*)/(.*)\.html$ index.php?c=$1&amp;id=$2  [L]
     RewriteRule ^(.*)/pag_(.*)\.html$ index.php?c=$1&amp;actual=$2  [L]

    se supone que al poner L, buscaría el que mas se parezca, pero a mi no me funciona, la segunda regla parecería que la ignora, ayúdeme por favor

  34. ismael zayas dice:

    ola juan
    solo quiero decirte q esta muy bueno el tutorial q subiste solo q es la primerva vez q copy hace
    una url amigable en mi wamp tengo hatcess tengo q modificar mi apache

  35. Juan dice:

    Hola he seguido los pasos que se dan en este post y funciona de maravilla el problema que tengo es que google no me detecta las paginas y me da error 404 cuando las paginas si que funcionan.

    El archivo htacces lo tengo de la siguiente forma

    1
    2
    
    RewriteEngine On
    RewriteRule ^([a-zA-Z0-9-]*)/([0-9]+)\.html$  /pueblos.php?pueblo=$1&amp;id=$2 [L]
  36. Vinfo dice:

    Al aplicar la reescritura de mis URLs se pierde la relación de los CSS y los JS, como puedo manejar esto???

  37. vampire dice:

    no puedo recuperar la variable, haber lo explico rapido.
    tengo 2 archivos index y clientes.php tengo el httacces con el codigo q pusieron

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    # Activar RewriteEngine
    RewriteEngine on
    RewriteBase /
    RewriteCond %{SCRIPT_FILENAME} !-d
    RewriteCond %{SCRIPT_FILENAME} !-f
     
    # Reescribir la URL solicitada por el usuario
    #   Entrada:  ID-NOMBRE
    #   Salida: pruducto.php?id=ID
    RewriteRule ^([0-9]+)\-([a-zA-Z0-9-]*)$ clientes.php?id=$1

    en index tengo un link

    1
    
    <a href="clientes/juan" rel="nofollow">Juan</a>

    en clientes tengo un

    1
    
    $id = $_GET['id'];

    porque no me imprime nada $id ??

  38. luis dice:

    hola bien e llegado a tu web buscando ayuda este es mi problema no se si puedas ayudarme
    mi web es asi

    1
    2
    3
    4
    
    http://www.miweb.com/index.php?cosas=paginas
    http://www.miweb.com/index.php?cosas=otra_pagina
    http://www.miweb.com/index.php?cosas=otra_mas
    http://www.miweb.com/index.php?cosas=

    lo que quiero es esto

    1
    2
    3
    
    http://www.miweb.com/paginas.html
    http://www.miweb.com/otra_pagina.html
    http://www.miweb.com/otra_mas.html

    lo de paginas son difententes cosas es la carpeta de las paginas php
    como iria en el .htaccess ps necesito algo de ayuda es algo simple pero ayuda es lo k necesito

  39. ganimedessp dice:

    Hola,

    Es muy bueno este post. Quería ver si me puedes ayudar.
    Tengo el .htaccess configurado y funcionando, pero me encuentro con un problema.

    La redirección es

    1
    
    http://www.dominio.com/nombre-del-articulo/775 dirige a http://www.dominio.com/articulo.php?e=775

    El problema es que cualquier url con el minimo de info correcta me lleva a la url redirigida

    1
    2
    
    http://www.dominio.com/lo-que-sea-que escriba/775
    me lleva a http://www.dominio.com/articulo.php?e=775

    Esto no está mal, pero me gustaría, como hace El Pais.es por ejemplo, que cuando se haga la redirección en la barra del navegador se restablezca la correcta…

    1
    2
    3
    4
    5
    
    Es decir, que la url, http://www.dominio.com/lo-que-sea/775
    lleve a la dirección
    http://www.dominio.com/articulo.php?e=775
    y en la barra de navegador se reestablezca
    http://www.dominio.com/nombre-de-articulo/775

    ¿Eso se puede hacer?¿cómo?

    Muchas gracias!

  40. Rolivar Peraza dice:

    Tengo el htaccess funcionando de maravilla, el único problema es que se pierden los estilos, el javascript y la imagenes. Puedo suponer que eso se debe a que no está interpretando las rutas de manera correcta.

    Ya varios hicieron esta pregunta y nadie ha respondido.

    ¿Cómo se soluciona este problema?

    Gracias.

  41. Rolivar Peraza dice:

    Como nadie supo responderme porque se perdían los estilos, pues tuve que solucionarlo por mi cuenta, y esto fue lo que encontré:

    Mi archivo htaccess tenía esto:

    1
    2
    3
    4
    5
    
    -------------------
    Options +FollowSymlinks
    RewriteEngine on
    RewriteRule ^(.+)/ ?s=$1
    --------------------

    en mi link ponía esta ruta:

    1
    
       http://misitio.com/mi-pagina/

    y la pagina se cargaba sin estilo, imagenes ni javascript, así que lo que hice fue cambiar mi htaccess a esto:

    1
    2
    3
    4
    5
    6
    7
    
    -------------------
    Options +FollowSymlinks
    RewriteEngine on
    RewriteRule ^(.+)\.html ?s=$1
    --------------------
     
    y mi link apuntando a http://misitio.com/mi-pagina.html

    Al parecer la barra (/) al final provoca una mala interpretación de las rutas, aunque no estoy seguro de que ese sea el motivo. Lo que si me parece interesante es que WordPress si usa la barra al final y todo funciona bien.

    En fin, al menos funcionó.

  42. Hola amigo, en primer lugar gracias por el tutorial, pero me gustaría hacerte una pregunta:
    Quiero dejar las url sin indentificador de producto, es decir que en lugar de aparecer “/333-producto..”. aparezca simplemente “/producto…”

    Según veo el funcionamiento de PrestaShop no se si esto se podrá hacer y además en el sitio que tengo el problema la importación se hace directamente desde los productos reales de la tienda, con lo cual los identificadores que quedan son bastante largos.

    Me gustaría minimizar en lo posible el problema y por lo menos poder poner los indentificadores al final de la url.

    • Juan Díaz-Bustamante dice:

      Hola,

      Si, eso con Prestashop no vas a poder hacerlo facilmente, requeriría cambiar muchas cosas del core y que las URLs no se generaran a través del htaccess sino a través de PHP. El problema es que ese “333″ es el id del producto, es decir, lo único importante de esa URL para que el código sepa de qué producto estamos hablando.

  43. Pablo dice:

    Hola Juan, primero que nada darte las gracias por el artículo que está excelente. Ahora tengo una consulta para realizarle y es que tengo un problema de visualización.
    Por ejemplo si visualizo así: miweb.com/marcas/nokia en ese caso se pierde el estilo de la página y no encuentra las imagenes ni nada.
    Ahora si visualizo así: miweb.com/marcas-nokia en ese caso se ve todo correctamente.

    Mi archivo htaccess es el siguiente:

    1
    
    Rewriterule ^marca/(\w+)?$ listadopormarca.php?marca=$1 [L]

    Muchas gracias por su tiempo!

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos necesarios están marcados *

*

Puedes usar las siguientes etiquetas y atributos HTML: <a href="" title="" rel=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">

2011-2012 © Copyright Emenia S.L. - Creación y Diseño web \ Marketing Online \ Comunicación - Todos los derechos reservados.     Mobile and Web Analytics