4
votes

I tried a few different questions:

  1. php - .htaccess make URL user friendly for multiple and dynamic parameters
  2. .htaccess for friendly URL with multiple variables
  3. User-friendly URLs instead of Query Strings?

The questions above were not useful, so I began to develop an alternative, but my code is returning an 404 error with multiple requests(code1), and with one request worked well(code2) So:

(code1) - Don´t Work - Multiple Resquest (code2) - Work Fine - Single Request

Code1


    Options +FollowSymLinks -MultiViews
    RewriteEngine on
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^([^/]*)/([^/]*)/([^/]*)/([^/]*)/([^/]*)/([^/]*)$ /~loja/index.php?a=$1&genero=$2&material=$3&cor=$4&tamanho=$5&Ordenacao=$6 [NC,L,QSA]
    RewriteCond %{THE_REQUEST} ^.*/index\.php 
    RewriteRule ^(.*)index.php$ /~loja/$1/$2/$3/$4/$5/$6 [R=301,L]  
    DirectoryIndex index.php

Now see the Correct Code:

Code2


    Options +FollowSymLinks -MultiViews
    RewriteEngine on
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^([a-zA-Z0-9_-]+)$ /~loja/index.php?a=$1 [NC,L,QSA]
    RewriteCond %{THE_REQUEST} ^.*/index\.php 
    RewriteRule ^(.*)index.php$ /~loja/$1 [R=301,L]  
    DirectoryIndex index.php

What is wrong with (code1)?

1
@anubhava if u can help me :)Bruno Pinna
What are the URLs you're trying to rewrite? Provide a few examples please including the ones that fail.sepehr
Original URL: site.com/index.php?a=botas-infantil&genero=feminino&material=couro&cor=marrom&tamanho=24-25&Ordenacao=MenorPrecoBruno Pinna
goal: site.com/botas-infantil/feminino/couro/marrom/tamanho/24-25/MenorPrecoBruno Pinna
With the code 2 work´s perfect, but add more request call error 404Bruno Pinna

1 Answers

4
votes

The first ruleset is not working because the goal URL contains 7 segments, but the RewriteRule matches 6 segments. If you add another /([^/]*) before the $ in the RewriteRule, it'll work.

So, it'd be:

RewriteRule ^([^/]*)/([^/]*)/([^/]*)/([^/]*)/([^/]*)/([^/]*)/([^/]*)$ /~loja/index.php?a=$1&genero=$2&material=$3&cor=$4&tamanho=$5&Ordenacao=$6 [NC,L,QSA]

You may make a segment/character optional by appending a ? character at the end of it.

The second part of the first ruleset is completely wrong and serves no purpose. First, you should note that THE_REQUEST variable contains the full HTTP request line as the documentation states:

THE_REQUEST contains the full HTTP request line sent by the browser to the server (e.g., GET /index.html HTTP/1.1). This does not include any additional headers sent by the browser. This value has not been unescaped (decoded), unlike most other variables below.

You don't want to use that, use REQUEST_URI instead.

The 404

The reason you're getting that 404 error, is that because the RewriteRule fails to match the request URI, the URL does not get rewritten to index.php. That directory hierarchy does not exist on the filesystem, thus the 404.

Optional URI segments

Your original ruleset was expecting exact count of URI arguments. If you need to be more flexible about this, you can try this ruleset which accepts 1-7 segments and map them to query strings:

<IfModule mod_rewrite.c>
    RewriteEngine on

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

    RewriteCond %{REQUEST_URI} !index\.php
    RewriteRule ^([^/]*)/?([^/]*)/?([^/]*)/?([^/]*)/?([^/]*)/?([^/]*)/?([^/]*)$ /~loja/index.php?a=$1&genero=$2&material=$3&cor=$4&tamanho=$5&Ordenacao=$6 [NC,L,QSA]
</IfModule>

When you test this, note the empty query strings. On the PHP side of things, you need to use empty() instead of isset(), to see if the querystring exists. As they're always set, but empty.

Excluding admin/

In order to exclude this rules to be applied on the admin/ path, you can update the above RewriteCond like this:

RewriteCond %{REQUEST_URI} !(index\.php|admin)