htaccess rewriting dynamic urls - .htaccess

How can I rewrite this url
http://www.example.com/index.php?test=<some dynamic data>
to
http://www.example.com/<some dynamic data>
I have tried
RewriteEngine on
RewriteRule index.php?test=(\w+)?$ $1
although it doesn't work.
How can this be done? And is it still possible for example to do echo $_GET['test'] with the rewritten url(or anything with the query)?

If the incoming url in the browser is the dynamic one:
http://www.example.com/<some dynamic data>
and you're trying to rewrite it to this, for your code:
http://www.example.com/index.php?test=<some dynamic data>
then try this:
RewriteEngine on
RewriteCond %{REQUEST_URI} !index.php
RewriteRule ^(.*)$ index.php?test=$1 [NC,L]
The last line takes anything that comes in, and sends it to index.php with the test parameter. The RewriteCond is making sure it doesn't do this with index.php itself, or it would be an infinite loop.
If you're trying to go the other way, and have your code create dynamic urls for displaying on your site, then that's somewhere else in your website code, wherever you're creating your html. Once created, this rule will rewrite them back to index.php.

Related

rewrite rule to convert php querystring to html

Please help me in writing correct .htaccess code to get the wanted result.
I have the following pages:
www.mydomain.com/?exam=/hp-certification/
www.mydomain.com/?exam=/cisco-certification/
www.mydomain.com/?exam=/oracle-exam-prep/
www.mydomain.com/?exam=/faq/
www.mydomain.com/?exam=/support/
And there are many more pages but you can notice that the fixed part is: www.mydomain.com/?exam=
Instead of using query string links, I want the following links to work as above pages:
www.mydomain.com/hp-certification/
www.mydomain.com/cisco-certification/
www.mydomain.com/oracle-exam-prep/
www.mydomain.com/faq/
www.mydomain.com/support/
and so on.
your link should be like this www.mydomain.com/?exam=hp-certification/ and the rewrite rule would like this in .htaccess file.
RewriteEngine On
RewriteRule ^([^/.]+)$ /?exam=$1 [L]
You can do that by using the following rules in your .htaccess file:
RewriteEngine On
RewriteCond %{QUERY_STRING} exam=(.+) [NC]
RewriteRule ^(.*)$ http://www.example.com/%1? [R=301,NC,L]
So what does the above do?
First, it will take the query exam= as a condition, if this condition is met then it will grab any version of the variable using (.+).
It will then rewrite the URL using 301 redirection to show http://www.example.com/anything/. The use of %1 is to grab the variable from exam= and then we use ? to stop the original query string from appearing on the end of the newly rewritten URL.
Make sure you clear your cache before testing this.

Rewrite URL Structure

I would like to change the URL structure of my site. My current URL structure is like this:
www.domain.com/events/events.php?location=san%20francisco
I want to change the URL structure to:
www.domain.com/events/san-francisco
My XMPL site map has the URLs listed like the first example. I want the search engines to index the URL like the second example. What are all the things I need to do to achieve this? The {city} in the location parameter is dynamic depending on the user's IP address. Do I need to change my XML sitemap to list new URL structure? What do I need to put in my .htaccess file. Do I need to change the actual URLs links on my website to the new structure or can I just use .htaccess?
This should work:
RewriteEngine On
RewriteCond %{THE_REQUEST} ^(GET|POST)\ /events\.php\?location=(.*)%20(.*)\ HTTP
RewriteRule ^ /events/%2-%3\? [R=302,L]
RewriteRule ^events/(.*)$ /events.php?location=$1 [L]
Changing R=302 to R=301 when you know it redirect correctly
EDIT:
RewriteEngine On
RewriteCond %{THE_REQUEST} ^(GET|POST)\ /(.*)/(.*)\.php\?location=(.*)%20(.*)&lid=(.*)&slid=(.*)\ HTTP
RewriteRule ^ /%3/%4-%5/%6/%7\? [R=302,L]
RewriteRule ^(.*)/(.*)/(.*)/(.*)$ /$1/$1.php?location=$2&lid=$3&slid=$4 [L]
RewriteCond %{THE_REQUEST} ^(GET|POST)\ /(.*)/(.*)\.php\?location=(.*)%20(.*)\ HTTP
RewriteRule ^ /%3/%4-%5\? [R=302,L]
RewriteRule ^([A-Za-z0-9]+)/([A-Za-z0-9]+)$ /$1/$1.php?location=$2 [L]
You have to use a .htaccess file similar to the one below. It will match fancy URL and forward the request to the right php file.
RewriteEngine On
RewriteRule ^([^/]*)/(.*)$ /$1/$1.php?location=$2
With this, both www.domain.com/events/events.php?location=san%20francisco and www.domain.com/events/san-francisco will lead to the same page.
But if you don't change your sitemap nor the links on your site, search engines won't know that.
You have then 2 solutions :
change all your links in your site and sitemap with the new structure URL
use a redirect rule to redirect "old" pages to the "new" ones
From what I know about SEO, the first option is the best. Or even better, a combination of both solutions : change all your links, and use a redirect 301 rule so pages already indexed by search engines will not lost their ranking and to avoid duplicate content.
RewriteRule ^([^/]*)/(.*).php?location=(.*)$ http://www.yourdomain.com/$1/$3 [R=301]

Rewriting old and new urls to same page with .htaccess

Have a page currently with the URL /results-details.php?mls_number=stringofnumbers.
I want it to re-write to: /results-details/stringofnumbers
However I want that to basically resolve back to the original page.
I'm also changing all the URLs on the site internally to point to the URL. So I have two re-write rules:
RewriteCond %{QUERY_STRING} mls_number=([0-9]+)$
RewriteRule (.*) /new-homes/results-details/%1? [R=301,C]
RewriteRule ^results-details/([0-9]+)$ results-details.php?mls_number=$1
The second rule works fine on it's own with internal links in the /results-details/stringofnumbers form, but the first one doesn't chain properly to the second one and not sure what I'm doing wrong.
Basically trying to retain any links to the old URLs that might be out there but start using the new URS internally.
Suggestions?
YOu need to match against the actual request and not the URI, because the rewrite engine loops:
RewriteCond %{THE_REQUEST} \ /new-homes/results-details\.php?mls_number=([0-9]+)
RewriteRule ^ /new-homes/results-details/%1? [L,R=301]
RewriteRule ^results-details/([0-9]+)$ results-details.php?mls_number=$1

Mod Rewrite for Code Igniter

I have a code igniter site that needs to accept incoming links in the format:
http://domain.tld/somename.html?id=IDREF
I need to create a rule for mod_rewrite that rewrites this URL to:
http://domain.tld/index.php/controller/somename/IDREF
I am having trouble writing the rule for the .htaccess file.
I thought this should work:
RewriteCond ${QUERY_STRING} ^(.*\.html\?id=.*)$
RewriteRule ^([^/]*)\.html\?id=(.*) /index.php/controller/$1/$2 [L]
But as I am a bit of a novice at mod_rewrite I can't get it to work.
Just to clarify I want the user to link to this ugly url and get sent to specific controller.
Try this:
RewriteCond ${QUERY_STRING} ^id=
RewriteRule ^(.*)\.html?id=(.*) index.php/controller/$1/$2 [L]
You might need to add a question mark after the second $2 if you get the original query string appended somehow after the rewrite

.htaccess and SEO URLs - why is this an infinite loop?

I have a dirty URL like this: http://www.netairspace.com/photos/photo.php?photo=3392.
I want to do something like http://www.netairspace.com/photos/OH-LTU/Finnair_Airbus_330-202X/OUL_EFOU_Oulu/photo_3392/ (and later support short URLs like http://www.netairspace.com/pic/3392/ but I'll leave that out).
So I have a script photo_seo_url.php, which takes the photo ID, builds the SEO URL, and does a redirect (302 for testing, 301 when I'm happy with it). I then planned to add .htaccess mod_rewrite rules so that on calling the old URL:
the old URL would be rewritten internally to photo_seo_url.php
photo_seo_url.php would 301/302 redirect to the SEO URL
the SEO URL would be rewritten internally to the original photo.php
That way I would, in theory, get the benefits of the SEO URL while being able to retire the old ones at my leisure.
These are the rules I used:
RewriteEngine on
RewriteRule ^photos/.*/photo_([0-9]+)/?$ photos/photo.php?photo=$1 [NC,L]
RewriteCond %{QUERY_STRING} photo=([0-9]+)
RewriteRule ^photos/photo\.php$ photos/photo_seo_url.php?photo=%1 [NC,L]
But that goes into an infinite redirect loop. Why, if these two are doing internal rewrites rather than external redirects - or is that what I'm missing?
I've solved the problem adding a new file showphoto.php, which does nothing but include the original photo.php, and changing line 2:
RewriteEngine on
RewriteRule ^photos/.*/photo_([0-9]+)/?$ photos/showphoto.php?photo=$1 [NC,L]
RewriteCond %{QUERY_STRING} photo=([0-9]+)
RewriteRule ^photos/photo\.php$ photos/photo_seo_url.php?photo=%1 [NC,L]
But I'd still like to understand why the original version goes into an infinite loop. I've missed or misunderstood something. Is my approach sound?
To answer your question, why does this loop occur? This is what happens with an SEO URI, with a GET /photos/OH-LTU/Finnair_Airbus_330-202X/OUL_EFOU_Oulu/photo_3392/, say.
Rule 1 fires converting this to a GET /photos/photo.php?photo=3392 which triggers an internal redirect which then restarts the scan of the .htaccessfile.
Rule 2 then fires converting this to a GET photos/photo_seo_url.php?photo=339 which triggers an internal redirect which again restarts the scan of the .htaccessfile.
No further matches occur and hence this is passed to the script photos/photo_seo_url.php which then does a 302 to /photos/OH-LTU/Finnair_Airbus_330-202X/OUL_EFOU_Oulu/photo_3392/ and the browser detects a redirection loop.
What you need happen is for rule 1 firing to prevent rule 2 firing even after an internal redirect. One way to do this is to set an environment variable, say END (which gets converted to REDIRECT_END on the next pass) and to skip the rules if this is set:
RewriteEngine on
RewriteBase /
RewriteRule ^photos/.*/photo_([0-9]+)/?$ photos/photo.php?photo=$1 [NC,E=END:1,L]
RewriteCond %{ENV:REDIRECT_END}:%{QUERY_STRING} ^:photo=([0-9]+)$
RewriteRule ^photos/photo\.php$ photos/photo_seo_url.php?photo=%1 [NC,L]
An alternative approach is to add a dummy noredir parameter to the rewritten URI and add a:
RewriteCond %{QUERY_STRING} !\bnoredir
to the original second rule. However, photo.php would need to ignore this. Hope this helps :-)
RewriteEngine on
RewriteRule ^photos/.*/photo_([0-9]+)/?$ photos/photo.php?photo=$1&rewritten [NC,L]
RewriteCond %{QUERY_STRING} !rewritten
RewriteCond %{QUERY_STRING} photo=([0-9]+)
RewriteRule ^photos/photo\.php$ photos/photo_seo_url.php?photo=%1 [NC,L]

Resources