.Htaccess for Friendly Url with Multiple Variables

.htaccess for friendly URL with multiple variables

Using just:

RewriteEngine On
Options -Indexes
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?page=$1 [L,QSA]

is fine then you can route the request within your script.

You split the page variable with explode() delimiter / and then set the variables.

$route = explode('/',$_GET['page']);

$page = isset($route[0]) ? $route[0] : null;
$subpage = isset($route[1]) ? $route[1] : null;
$yada = isset($route[2]) ? $route[2] : null;

Many MVC frameworks use this method. Its called routing.

htaccess - pretty url with multiple variables

With your shown samples, please try following. This considers that you want to hit URL like: http://localhost:80/sky.php?c=something&id=9&s=anything in browser which should be redirected to http://localhost:80/something/9/anything here.

Please make sure to clear your browser cache before testing your URLs.

RewriteEngine ON
##This rule handles to change from non-friendly URL to friendly URL in browser.
RewriteCond %{THE_REQUEST} \s/(?:[^.]*)\.php\?c=([^&]*)&id=([^&]*)&s=([^\s&]*) [NC]
RewriteRule ^ /%1/%2/%3? [R=301,L]

##This rule internally rewrites friendly url to non-friendly url.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]*)/([^/]*)/([^/]*)/?$ sky.php?c=$1&id=$2&s=$3 [L]

Friendly URL for multiple and long queries

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)

URL rewrite with .htaccess for multiple-language site (multiple variables)

That's not possible the way you're trying to do it since apache doesn't know when it's a language value (like no or eng) or when it's a page (like about-us.)

Let me explain you how I would do this:

RewriteRule ^([^/]+)/?$ /index.php?g1=$1 [L,QSA]

so now if I'd go to example.com/about-us/ then this will be the same as example.com/index.php?g1=about-us or the other (your language url) would be example.com/index.php?g1=no.

now in PHP you need to check it like this:

if($_GET['g1'] == "no")
//Norwegian language
else if($_GET['g1'] == "about-us")
//About us page
else
//Page doesn't exist

.htaccess multiple parameters in URL

You can't do this "indefinitely" using .htaccess alone. You would need to decide on the maximum number (N) of parameters and write a directive for each in order: N, N-1, N-2, ... 1. However, you are also limited by the number of backreferences that are supported. ie. With just $1 to $9, you are limited to 4 parameters, using your method of including the parameter name in the URL path as well.

For example:

# 3 additional parameters
RewriteRule ^([\w-]+)/([\w-]+)/([\w-]+)/([\w-]+)/([\w-]+)/([\w-]+)/([\w-]+)/?$ index.php?page=$1&$2=$3&$4=$5&$6=$7 [L]

# 2 additional parameters
RewriteRule ^([\w-]+)/([\w-]+)/([\w-]+)/([\w-]+)/([\w-]+)/?$ index.php?page=$1&$2=$3&$4=$5 [L]

# 1 additional parameter
RewriteRule ^([\w-]+)/([\w-]+)/([\w-]+)/?$ index.php?page=$1&$2=$3 [L]

# No parameters (just the page)
RewriteRule ^([\w-]+)/?$ index.php?page=$1 [L]

These all allow an optional trailing slash (as in your current example). However, you are better off deciding whether a trailing slash is required or not and choosing one or the other. Having the trailing slash optional simply promotes duplicate content.

This URL pattern is also a bit too "generalised" in my opinion. It is more usual to be specific and avoid including the parameter name in the URL. For example: example.com/home/value1/value2/value2 - the parameter names (param1, param2, etc.) would be hardcoded in the RewriteRule substitution. This would also allow you to have twice as many parameters.

RewriteRule ^([\w-]+)?$ index.php?page=$1 [L]
RewriteRule ^([\w-]+)/?$ index.php?page=$1 [L]

You shouldn't need two directives here. (Providing the DirectoryIndex is set correctly.)

Rewriting URLs with htaccess, multiple parameters

Please don't create OR test rules on online sites, they are NOT trust worthy, so kindly test these rules into your localhost OR apache.

With your shown samples/attempts, please try following htaccess rules. Considering that you are hitting URL https://mywebsite.com/pages/article.html?id=1&title=Title-Goes-Here in browser AND you want to redirect it to URL https://mywebsite.com/pages/article/1/Title-Goes-Here in browser.

Please make sure to clear your browser cache before testing your URLs.

RewriteEngine ON
##External redirect in browser rules here....
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{THE_REQUEST} \s/([^/]*)/([^.]*)\.html\?id=([^&]*)&title=(\S+)\s [NC]
RewriteRule ^ /%1/%2/%3/%4? [R=301,L]

##Internal rewrite to html file rules here....
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]*)/([^/]*)/([^/]*)/([^/]*)/?$ $1/$2.html?id=$3&title=$4 [QSA,NC,L]

HTACCESS: Dynamic rewrite url with multiple variables

I'm not an expert but I think this will do it for you:

RewriteEngine On

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ([^/]+)/([^/]+) index.php?p=$1&article=$2 [L]

Where [^/]+ matches everything except /, result when tested on htaccess.madewithlove.be

Sample Image


EDIT:

as I totally forgot that the second parameter is optional, the great update in the OP almost did it except the fact that it adds a / at the start of parameter2 value, because $2 is capturing the outer group, while we need the inner one, as shown in this image:

Sample Image


Instead replace $2 with $3 and this should fix it:

RewriteRule ^([^/]+)(/([^/]+))? ?p=$1&article=$3   [L]

Sample Image



Related Topics



Leave a reply



Submit