htaccess redirect with multiple parameter - .htaccess

I am using following htaccess rewrite for clean URL:
RewriteRule ^([^/]+)/?$ category.php?cat=$1 [L,QSA]
RewriteRule ^([^/]+)/([^/]+)/?$ subcategory.php?cat=$1&subcat=$2 [L,QSA]
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/?$ item.php?cat=$1&subcat=$2&item=$3 [L,QSA]
And I get clean URL like:- domain.com/SHOE/MEN/ITEM-NAME
Now I want change URL to be:- 1. domain.com/BOOTS/MEN/ITEM-NAME
and similar changes at parent level like: 2. domain.com/BOOTS/MEN and 3. domain.com/BOOTS
I tried with one additional line
RewriteRule ^SHOE/.*$ /BOOTS/$1 [L,R]
But still not working. Sorry If I made it complex. Thank you for help in advance.

Your question is not really clear, but I assume you want to redirect incoming browser requests to URLs using BOOTS instead of SHOE, whilst keeping the rest of the requested URL as it is...
For that try something like that:
RewriteEngine on
RewriteRule ^/?SHOE(.*)$ /BOOTS$1 [R=301,END]
That rule should be placed at the beginning of a possible series of rewrite rules. If you are using an old apache http server you might have to use the L flag instead of END. That also means you might have to take additional measures to prevent an endless rewriting loop.
And a general hint: you should always prefer to place such rules inside the http servers host configuration instead of using dynamic configuration files (".htaccess"). Those files are notoriously error prone, hard to debug and they really slow down the server. They are only provided as a last option for situations where you do not have control over the host configuration (read: really cheap hosting service providers) or if you have an application that relies on writing its own rewrite rules (which is an obvious security nightmare).

Related

Redirect htaccess rule giving 404

I have .htaccess file for seo friendly url. My standard url is;
index.php?p=user
And I can access this url by typing;
www.mydomain.com/user
Everything is fine until here. What I also want to do is to crate a seo url for the following url;
index.php?p=user&username=john
and the seo url should be as follows;
www.mydoamin.com/user/john
I have tried the following and it keeps throwing 404 error.
RewriteRule ^user/([^/]*)$ /index.php?p=user&username=$1 [L]
Can anybody tell me what is wrong here?
Here is the current .htaccess code
RewriteEngine On
RewriteRule ^(.+)$ index.php?p=$1 [L,QSA]
RewriteRule ^user/([^/]*)$ /index.php?p=user&username=$1 [L]
Considering the current configuration you added to the question the issue might be that you need to reverse the order of those directives:
RewriteEngine On
RewriteRule ^user/([^/]*)$ /index.php?p=user&username=$1 [L]
RewriteRule ^(.+)$ index.php?p=$1 [L,QSA]
The reason is that the directives get processed from top to bottom. That means that you need to implement more specific rules, so exceptions earlier, so further up in the file. Because the pattern ^(.+)$ will match all requests.
There are some additional modifications I would suggest. But you will have to test that, since I have only a very limited insight into your setup:
RewriteEngine On
RewriteRule ^/?user/([^/]+)/?$ /index.php?p=user&username=$1 [END]
RewriteRule ^/?([^/]+)/?$ /index.php?p=$1 [END,QSA]
In case you receive an internal server error (http status 500) using the rule above then chances are that you operate a very old version of the apache http server. You will see a definite hint to an unsupported [END] flag in your http servers error log file in that case. You can either try to upgrade or use the older [L] flag, it probably will work the same in this situation, though that depends a bit on your setup.
This implementation will work likewise in the http servers host configuration or inside a distributed configuration file (".htaccess" file). Obviously the rewriting module needs to be loaded inside the http server and enabled in the http host. In case you use a distributed configuration file you need to take care that it's interpretation is enabled at all in the host configuration and that it is located in the host's DOCUMENT_ROOT folder.
And a general remark: you should always prefer to place such rules in the http servers host configuration instead of using distributed configuration files (".htaccess"). Those distributed configuration files add complexity, are often a cause of unexpected behavior, hard to debug and they really slow down the http server. They are only provided as a last option for situations where you do not have access to the real http servers host configuration (read: really cheap service providers) or for applications insisting on writing their own rules (which is an obvious security nightmare).

Change URL ending with Query String

I've been using a set of redirect rules for a while that have been working perfectly.
I've recently expanded a part of my website and need to change the ending of a certain URL.
Old URL: /clan/{query-string}/tracking/war
New URL: /clan/{query-string}/tracking/warlog
I've changed my .htaccess file so the new URL works, but I need the old URL to redirect to the new one.
Currently, this is how I'm redirecting in .htaccess:
# Rewrite Clan Tracking-Warlog URL
RewriteEngine On
RewriteCond %{THE_REQUEST} /clanTracking_main.php\?name=([^\s]+) [NC]
RewriteRule ^.+$ /clan/%1/tracking/warlog [L,R]
RewriteRule ^clan/([^/]+)/tracking/warlog clanTracking_main.php?name=$1 [L]
It works perfectly but I just need help with the redirection.
Thanks for your help in advance!
I'd say the first rule below is what you ask...
I also made some other modifications which appeared to make sense to me...
# Rewrite Clan Tracking-Warlog URL
RewriteEngine On
# redirect old to new
RewriteRule ^/?clan/([^/]+)/tracking/war$ /clan/$1/tracking/warlog [R=301]
# pick name from get argument and redirect
RewriteCond %{QUERY_STRING} (?:^|&)name=([^\s]+)(?:&) [NC]
RewriteRule ^/?clanTracking_main\.php$ /clan/%1/tracking/warlog [R=301]
# rewrite to php
RewriteRule ^/?clan/([^/]+)/tracking/warlog$ clanTracking_main.php?name=$1 [END]
It is a good idea to start out with a 302 temporary redirection and only change that to a 301 permanent redirection later, once you are certain everything is correctly set up. That prevents caching issues while trying things out...
In case you receive an internal server error (http status 500) using the rule above then chances are that you operate a very old version of the apache http server. You will see a definite hint to an unsupported [END] flag in your http servers error log file in that case. You can either try to upgrade or use the older [L] flag, it probably will work the same in this situation, though that depends a bit on your setup.
This implementation will work likewise in the http servers host configuration or inside a distributed configuration file (".htaccess" file). Obviously the rewriting module needs to be loaded inside the http server and enabled in the http host. In case you use a distributed configuration file you need to take care that it's interpretation is enabled at all in the host configuration and that it is located in the host's DOCUMENT_ROOT folder.
And a general remark: you should always prefer to place such rules in the http servers host configuration instead of using distributed configuration files (".htaccess"). Those distributed configuration files add complexity, are often a cause of unexpected behavior, hard to debug and they really slow down the http server. They are only provided as a last option for situations where you do not have access to the real http servers host configuration (read: really cheap service providers) or for applications insisting on writing their own rules (which is an obvious security nightmare).

I need to redirect my dynamic URL to a clean and SEO friendly static URL using htaccess

I am a web developer. I have developed a news portal for my client. But the URLs of the articles are dynamic and I need to redirect it to a static URL for SEO purpose.
The current URL : https://example.com/single-post.php?id=1&category=news&title=this-is-a-title
Desired URL : https://example.com/news/this-is-a-title
Someone please help me.
I have wrote this :
RewriteCond %{QUERY_STRING} (?:^|&)id=(\d+)(?:&|$)
RewriteCond %{QUERY_STRING} (?:^|&)title=([^&]+)(?:&|$)
RewriteRule ^/?single-post\.php$ /%2/%1 [R=301]
RewriteRule ^/?(.*)/(\d+)$ single-post.php?title=$1&id=$2 [END]
But the URL output is not what I expected. It is like :
https://example.com/this-is-title/?id=1&title=this-is-title
The only title came first without the id and then the old format came again after the slash. I can't understand what is going on here.
What you ask actually is not possible. There is no way for the rewriting module to somehow magically guess the numerical ID of that object you request. What you can actually do is publish URL in the style of https://example.com/news/1/this-is-a-title. Notice the ID in there, that is what is usally done. For that his should point you into the right direction:
RewriteEngine on
RewriteRule ^/?news/(\d+)/(.*)/?$ /single-post.php?id=$1&category=news&title=$2 [END]
Typically your application logic will only need the numerical ID of the requested object to fetch it from your database. So you typically can silently drop the title in the internal rewriting which makes things even more simple:
RewriteEngine on
RewriteRule ^/?news/(\d+) /single-post.php?id=$1&category=news [END]
In case you receive an internal server error (http status 500) using the rule above then chances are that you operate a very old version of the apache http server. You will see a definite hint to an unsupported [END] flag in your http servers error log file in that case. You can either try to upgrade or use the older [L] flag, it probably will work the same in this situation, though that depends a bit on your setup.
This rule will work likewise in the http servers host configuration or inside a dynamic configuration file (".htaccess" file). Obviously the rewriting module needs to be loaded inside the http server and enabled in the http host. In case you use a dynamic configuration file you need to take care that it's interpretation is enabled at all in the host configuration and that it is located in the host's DOCUMENT_ROOT folder.
And a general remark: you should always prefer to place such rules in the http servers host configuration instead of using dynamic configuration files (".htaccess"). Those dynamic configuration files add complexity, are often a cause of unexpected behavior, hard to debug and they really slow down the http server. They are only provided as a last option for situations where you do not have access to the real http servers host configuration (read: really cheap service providers) or for applications insisting on writing their own rules (which is an obvious security nightmare).
UPDATE:
in your comment to this answer you suggest to also do an explit redirection in case the target URL is used on the client side. Here is a variant of version 2 above which adds that redirection:
RewriteEngine on
RewriteCond %{QUERY_STRING} (?:^|&)id=(\d+)(?:&|$)
RewriteRule ^/?single-post\.php$ /news/%1 [R=301]
RewriteRule ^/?news/(\d+) /single-post.php?id=$1&category=news [END]
A variant of version 1 would look similar:
RewriteEngine on
RewriteCond %{QUERY_STRING} (?:^|&)id=(\d+)(?:&|$)
RewriteCond %{QUERY_STRING} (?:^|&)title=([^&]+)(?:&|$)
RewriteRule ^/?single-post\.php$ /news/%1/%2 [R=301]
RewriteRule ^/?news/(\d+) /single-post.php?id=$1&category=news [END]
Is is a good idea to start with a 302 redirection first. And only change that to a 301 redirection once everything works fine. That saves you from hassles with client side caching while you are still trying things out.

How to rewrite rule based on folder and file type in htaccess?

I have been trying to implement a rewrite rule for a downloads folder so that I can serve files that end with .gif, .jpg, .png, .css, .js or .swf and send users to user.php for every other file.
For example: I should hit this URL : www.somewhere.com/downloads/mypic.jpg,
but when I try : www.somewhere.com/downloads/my.pdf I should be redirected to user.php.
So far, I have :
RewriteRule ^*/downloads//!(.*)\.(gif|jpg|png|jpeg|css|js|swf)$ /base/user.php?a=$1 [R=302,L]
Here are some samples for expected behaviour :
good
www.somewhere.com/downloads/mypic.jpg
www.somewhere.com/downloads/otherpic.png
www.somewhere.com/downloads/scripts/jquery.js
bad
www.somewhere.com/downloads/my.pdf > send the request to www.somewhere.com/base/user.php
www.somewhere.com/downloads/readme.txt > send the request to www.somewhere.com/base/user.php
www.somewhere.com/downloads/postman.json > send the request to www.somewhere.com/base/user.php
This probably is what you are looking for:
RewriteEngine on
RewriteRule ^/?downloads/([^/]+)\.(gif|jpg|png|jpeg|css|js|swf)$ /base/user.php?a=$1 [R=302]
The above rule will redirect the browser, so change the visible URL. That is what you suggest yourself in your question. In case you want to implement an internal rewriting instead you need to alter the flag slightly:
RewriteEngine on
RewriteRule ^/?downloads/([^/]+)\.(gif|jpg|png|jpeg|css|js|swf)$ /base/user.php?a=$1 [END]
This rule will work in the http servers host configuration and likewise in dynamic configuration files (.htaccess). Obviously the rewriting modules must be enabled in your http server. If you decide to use a dynamic configuration you need to enable its interpretation first, take a look at the AllowOverride directive in the official documentation for that.
And a general hint: you should always prefer to place such rules inside the http servers (virtual) host configuration instead of using dynamic configuration files (.htaccess style files). Those files are notoriously error prone, hard to debug and they really slow down the server. They are only supported as a last option for situations where you do not have control over the host configuration (read: really cheap hosting service providers) or if you have an application that relies on writing its own rewrite rules (which is an obvious security nightmare).
In your modification of the question it becomes clear that what you try to implement actually is the opposite of what you apparently asked before. Here is a modified version of the above rule:
RewriteEngine on
RewriteCond %{REQUEST_URI} !^/downloads/[^/]+\.(gif|jpg|png|jpeg|css|js|swf)$
RewriteRule !^/?downloads/([^/]+\.\w+)$ /base/user.php?a=$1 [R=302]
And another general remark: often it makes more sense to not grant any access directly to files in the server side physical file system but to implement a router script instead which controls access to all such files. This allows for more fine grained access control and keeps the physical layout separated from the URL set you define.
Have this rule inside downloads/.htaccess file (create it if it doesn't exist):
RewriteEngine On
RewriteCond %{REQUEST_URI} !\.(gif|png|jpe?g|css|js|swf)$ [NC]
RewriteRule .* /base/user.php?a=$0 [R=302,L,NC,QSA]
I decided to redirect, when a request to a forbidden extension exists. This worked for me :
RewriteRule ^/downloads/(..(pdf|txt|json))$ /base/user.php?a=$0 [R=302,L]

Redirecting URLs using RegExp and Mod Rewrite

While upgrading Magento to 1.9.3.4 it overwrote the .htaccess file and now I am left with 2000+ broken links that I had manually created.
Since the old product URLs had a random number at the end and now they don't have so I am looking for a way to redirect them.
Old URLs Structure:
http://example.com/category-1/subcategory/product-name-1421.html
http://example.com/category-2/subcategory/product-name-5421.html
http://example.com/category-3/subcategory/product-name-5891.html
New URLs Structure:
http://example.com/category-1/subcategory/product-name.html
http://example.com/category-2/subcategory/product-name.html
http://example.com/category-3/subcategory/product-name.html
I know I can use RegExp something like RewriteRule ^category/subcategories/(.+?)(-[0-9]+)?$ category/subcategories/$1 [L,R=301] but I couldn't get it working.
I'd say this probably is what you are looking for:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/?category/subcategory/(.+?)-\d+\.html$ /category/subcategory/$1.html [R=301]
For this you obviously need the rewriting module activated in your http server. And in case you want to use a dynamic configuration file (see below...) you need to enable that too (see the AllowOverride directive).
And a general hint: you should always prefer to place such rules inside the http servers (virtual) host configuration instead of using dynamic configuration files (.htaccess style files). Those files are notoriously error prone, hard to debug and they really slow down the server. They are only provided as a last option for situations where you do not have control over the host configuration (read: really cheap hosting service providers) or if you have an application that relies on writing its own rewrite rules (which is an obvious security nightmare).

Resources