.htaccess 301 redirection removing white space [duplicate] - php

So here's my problem. I took over a site that has has a bunch of pages indexed that have %20 indexed in Google. This is simply because the person decided to just use the tag name as the title and url slug. So, the urls were something like this:
http://www.test.com/tag/bob%20hope
http://www.test.com/tag/bob%20hope%20is%20funny
I have added a new field for the url slug and string replaced all spaces with dashes. While I have no problem linking to these new pages and getting the data, I need to 301 redirect the old URLs to the new URLs, which would be something like:
http://www.test.com/tag/bob-hope
http://www.test.com/tag/bob-hope-is-funny
So, it needs to be able to account for multiple spaces. Any questions? :)

Use these rules in your .htaccess file:
Options +FollowSymlinks -MultiViews
RewriteEngine on
RewriteBase /
# keep replacing space to hyphen until there is no space use internal rewrite
RewriteRule ^([^\s%20]*)[\s%20]+(.*)$ $1-$2 [E=NOSPACE:1]
# when there is no space make an external redirection
RewriteCond %{ENV:NOSPACE} =1
RewriteRule ^([^\s%20]+)$ $1 [R=301,L]
This will replace all space characters (\s or %20) to hyphen -
So a URI of /tag/bob%20hope%20is%20funny will become /tag/bob-hope-is-funny with 301
Brief Explanation: If there are more than 1 space in URI then 1st RewriteRule is fired recursively replacing each space character with hyphen - until there is no space left. This rule will only rewrite internally.
Once no space is left 2nd RewriteRule is fired which just uses a 301 redirect to the converted URI.

Building on #anhubhava's answer, it's close, but that will also match %,2 or 0 in the URL, and it can cause a loop on apache 2.2 if you don't use the DPI parameter. The full script should look like this:
Options FollowSymlinks MultiViews
RewriteEngine on
RewriteBase /
# keep replacing space to hyphen until there is no space use internal rewrite
RewriteRule ^([^\s%20]*)(?:\s|%20)+(.*)$ $1-$2 [N,E=NOSPACE:1,DPI]
# when there is no space make an external redirection
RewriteCond %{ENV:NOSPACE} =1
RewriteRule ^([^\s%20]+)$ $1 [R=301,L]
I've also added the N (Next) parameter as this then forces the rules to be re-evaluated from the start straight after this rule if it matches. If this isn't there, you can get problems if you're using apache as a reverse proxy as it's unlikely that it'll get to the end of the rewrites before something else happens.

Related

htaccess multiple query string not working

I want to get this URL:
example.com/scooter-details/1/vespa-sprint
But the URL I get is:
example.com/scooter-details.php?scooter_id=1&scooter_brand=vespasprint&scooter_model=
The scooter_model "sprint" is in the scooter_brand query, Normally it has to be scooter_brand=vespa&scooter_model=sprint. Hope you can help me with this
Here is the htaccess code
Options +FollowSymLinks -MultiViews
RewriteEngine On
# SEO FRIENDLY URL
# Redirect "/scooter-details.php?service_id=<num>" to "/scooter-details/<num>"
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{QUERY_STRING} ^scooter_id=(\d+)&scooter_brand=([^/.]+)&scooter_model=([^/.]+)$
RewriteRule ^(scooter-details)\.php$ /$1/%1/$2%2-$3%3? [QSD,L,R=301,N]
# Rewrite "/scooter-details/<num>" back to "scooter-details.php?service_id=<num>"
RewriteRule ^(scooter-details)/(\d+)/([^/]+)$ $1.php?scooter_id=$2&scooter_brand=$3&scooter_model=$4 [L]
You most probably need the NE (noescape) flag on the RewriteRule directive if you are capturing elements of the query string (which is already URL-encoded) and using these to build the URL-path. Otherwise you will end up doubly-URL-encoding parts of the resulting URL-path - which is what this looks like.
%2520 is a doubly URL-encoded space. ie. you would seem to have %20 (ie. a space) in the query string you are capturing from.
However, the rule you have posted does not seem to relate to the example URLs given?

Removing .php Extension from Specific URL

I've tried searching but can't find a solution that works.
I'd like to remove the .php extension and add a trailing slash from a specific URL (about.php).
For instance...
www.example.com/about.php should redirect to www.example.com/about/
and
www.example.com/about should redirect to www.example.com/about/
I've tried various RewriteRules in .htaccess but none of them worked the way I needed them to.
The following adds the trailing slash, and I can access the page without the extention... but the .php version still shows up.
RewriteEngine On
RewriteBase /
RewriteRule ^about/$ about.php [END,QSA,NC]
Does anyone have any idea how to get this working?
To externally redirect /about.php (and /about - no trailing slash) to /about/ (for the benefit of search engines and external third parties that may have indexed/linked to the old URL) you would need to add something like the following before your existing rewrite:
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^about(\.php)?$ /about/ [R=302,L]
The condition that checks against the REDIRECT_STATUS environment variable is to ensure we only redirect direct requests and not already rewritten requests by the later rewrite. REDIRECT_STATUS is empty on the initial request and gets set to the HTTP status (ie. "200" on success) after the first rewrite.
The RewriteRule pattern matches both /about and /about.php and redirects to /about/.
Note that this is a 302 (temporary) redirect. Only change it to a 301 (permanent) - if that is the intention - once you have confirmed it works OK. This is to avoid caching issues (301s are cached persistently by the browser). Likewise, if you have previously experimented with 301s then you will need to make sure the browser is cleared before testing.
UPDATE#1: If I wanted to do this to multiple pages
If you have just two pages (as in your example/comment) then you can combine both rules into one (rather than duplicating the rule block). For example:
RewriteEngine On
RewriteBase /
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^(about|contact)(\.php)?$ /$1/ [R=302,L]
RewriteRule ^(about|contact)/$ $1.php [END,QSA,NC]
The $1 backreference will hold either "about" or "contact" from the capturing group in the RewriteRule pattern.
UPDATE#2: ... I'm starting to add a lot of pages and I'm afraid the list will get out of control. Is there a better way to handle tons of pages... like 50+?
If all your pages are files in the document root then you could generalise the regex and essentially rewrite everything. For example:
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^([\w-]+)(\.php)?$ /$1/ [R=302,L]
RewriteRule ^([\w-]+)/$ $1.php [END,QSA,NC]
This is no longer "specific", as it redirects/rewrites any URL that simply "looks like" a valid request.
\w is the shorthand character class for any word character (ie. a-z, A-Z, 0-9 and _), to this we add the hyphen. So your URLs/filenames can only consist of those characters.
The above will match /about/, /contact/, /something-else/ and /foo_BAR_123/, etc. But it won't match /foo.jpg, /foo/about/ or /foo.bar/, etc.
If required, you could first check that the file exists before rewriting to it (or redirecting), but that is relatively expensive and probably not required here.
You can use index.php instead.
index page does not show up on browser address.
You can create http://www.example.com/about/index.php and on the browser, it will show as:
http://www.example.com/about/
If you need to redirect from http://www.example.com/about.php I can recommend use header http-equiv:
< meta http-equiv="refresh" content="0; URL='http://www.example.com/about/'" />

url redirect from _ to - htaccess

I have problem in my URL.
This is my code in htaccess:
RewriteRule ^music-(.*)-([0-9_]+)\.html$ /artiste.php?g=$1&page=$2 [NC,L]
So some URL on Google or Bing could be showing like this music_(.*)_([0-9_]+)\.html
If possible I want to change _ to - with htaccess.
I want any url with _ to change to -, because all links work correct with - but in my research some URLs have _ so I want to replace them with -.
example:
Error : http://www.example.com/me_like_this.html
Correct : http://www.example.com/me-like-this.html
You can use the following in your /.htaccess file:
RewriteEngine On
# Replace underscores with hyphens, set the environment variable,
# and restart the rewriting process. This essentially loops
# until all underscores have been converted to hyphens.
RewriteRule ^([^_]*)_(.*)$ $1-$2 [E=underscore:yes,N]
# Then, once that is done, check if the underscore variable has
# been set and, if so, redirect to the new URI. This process ensures
# that the URI is rewritten in a loop *internally* so as to avoid
# multiple browser redirects.
RewriteCond %{ENV:underscore} yes
RewriteRule (.*) /$1 [R=302,L]
Then add your rule afterwards:
RewriteRule ^music-(.+)-(\d+).html$ /artiste.php?g=$1&page=$2 [NC,L]
If this is working for you, and you would like to make the redirects cached by browsers and search engines, change 302 to 301.
Note: In your RewriteRule I have changed .* to .+ so it only matches one or more characters, instead of zero or more characters. Additionally, I have changed [0-9_]+ to \d+, which is the shorthand equivalent without including underscores, which would be converted to hyphens anyway. If you want to include hyphens in the last capture group, then change (\d+) to ([\d-]+).
RewriteEngine On
RewriteRule ^(.*)_(.*)$ /$1-$2 [L,R=301]
RewriteRule ^music-(.*)-([0-9_]+)\.html$ /artiste.php?g=$1&page=$2 [NC,L]
Please try this.

How to change dynamic url into static url in php

I want to change my dynamic URL link into static URL link while using .haccess, its showing error 500, I have so many links with different URL links name.
Options +FollowSymLinks
RewriteEngine on
RewriteRule product/categoryid/(.*)/productid/(.*)/ product.php?categoryid=$1&productid=$2
RewriteRule product/categoryid/(.*)/productid/(.*) product.php?categoryid=$1&productid=$2
From your question, it is assumed you're running from your domain root. As such, place the following in your /.htaccess file:
Options +FollowSymLinks
RewriteEngine On
RewriteRule ^product/categoryid/(\d+)/productid/(\d+)/?$ /product.php?categoryid=$1&productid=$2 [NC,QSA,L]
Changes made:
I've condensed your two rules into one rule (Don't Repeat Yourself), making the ending forward slash (/) optional
Match beginning (^) and end ($) of the expression
(.*) is now (\d+) which matches digits only (assumed to be IDs)
Added No Case (NC), Query String Append (QSA) and Last (L) flags to the rule
Note: You need to ensure that mod_rewrite is indeed enabled. If the 500 Internal Server Error still persists, please check your Apache logs.

PHP all GET parameters with mod_rewrite

I am designing my application. And I should make the next things. All GET parameters (?var=value) with help of mod_rewrite should be transform to the /var/value. How can I do this? I have only 1 .php file (index.php), because I am usign the FrontController pattern. Can you help me with this mod_rewrite rules?Sorry for my english. Thank you in advance.
I do something like this on sites that use 'seo-friendly' URLs.
In .htaccess:
Options +FollowSymLinks
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* /index.php [L]
Then on index.php:
if ($_SERVER['REQUEST_URI']=="/home") {
include ("home.php");
}
The .htaccess rule tells it to load index.php if the file or directory asked for was not found. Then you just parse the request URI to decide what index.php should do.
The following code in your .htaccess will rewrite your URL from eg. /api?other=parameters&added=true to /?api=true&other=parameters&added=true
RewriteRule ^api/ /index.php?api=true&%{QUERY_STRING} [L]
.htaccess
RewriteEngine On
# generic: ?var=value
# you can retrieve /something by looking at $_GET['something']
RewriteRule ^(.+)$ /?var=$1
# but depending on your current links, you might
# need to map everything out. Examples:
# /users/1
# to: ?p=users&userId=1
RewriteRule ^users/([0-9]+)$ /?p=users&userId=$1
# /articles/123/asc
# to: ?p=articles&show=123&sort=asc
RewriteRule ^articles/([0-9]+)/(asc|desc)$ /?p=articles&show=$1&sort=$2
# you can add /? at the end to make a trailing slash work as well:
# /something or /something/
# to: ?var=something
RewriteRule ^(.+)/?$ /?var=$1
The first part is the URL that is received. The second part the rewritten URL which you can read out using $_GET. Everything between ( and ) is seen as a variable. The first will be $1, the second $2. That way you can determine exactly where the variables should go in the rewritten URL, and thereby know how to retrieve them.
You can keep it very general and allow "everything" by using (.+). This simply means: one or more (the +) of any character (the .). Or be more specific and e.g. only allow digits: [0-9]+ (one or more characters in the range 0 through 9). You can find a lot more information on regular expressions on http://www.regular-expressions.info/. And this is a good site to test them: http://gskinner.com/RegExr/.
AFAIK mod_rewrite doesn't deal with parameters after the question mark — regexp end-of-line for rewrite rules matches the end of path before the '?'. So, you're pretty much limited to passing the parameters through, or dropping them altogether upon rewriting.

Categories