Beginner's apache mod_rewrite assistance - apache

I am not really familiar with apache mod_rewrite.
I have url parameters such as {domain}/index.php?blog=5
I simply want to make it {domain}/home.php?client=5
Is it a task as simple as it sounds and can anyone help?

The following might work, give it a try
RewriteCond %{REQUEST_URI} ^/home.php [NC]
RewriteCond %{QUERY_STRING} client=([0-9]+) [NC]
RewriteRule (.*) http://%{REMOTE_HOST}/index.php?blog=%1 [L]

That seems pretty simple, to be honest — once you get your head into mod_rewrite, it's not that complex.
It sounds like you want to add
RewriteEngine on
RewriteRule ^/index.php?blog=(.+)$ /home.php?client=$1
to your configuration.
Some caveats:
If you are putting this in a .htaccess file, then remove the / from the RewriteRule line.
If you want to make this case-insensitive, add [NC] to the end of that same line.
If you want users to see the URL change (so sending a 302 Found redirection to the browser), then add [R] to the end of the RewriteRule line.
If you want both a 302 Found and for the URL to be case-sensitive, combine the two instructions as [NC,R] at the end of the RewriteRule line.
It's definitely worth reading the mod_rewrite docs, but the rule above should be all you need for this use-case.

Related

Rewrite Rule - need guidance

I need to do some redirecting to get some internal links to work but I'm having a complete block.
The url would be http://www.something.com/faqs/What_happens_if_I_move_home?
redirected to http://www.something.com/faqs/index/What_happens_if_I_move_home?
but it must look like the original url. I'm sure there is a simple answer but rewrite rules and regex are a mystery to me at times.
I did try RewriteRule ^faqs(/.*)?$ /faqs/index$1 [R,L,NC]
amongst many others!
try this:
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/faqs/index
RewriteRule ^faqs/(.*) /faqs/index/$1 [L,NC]

How to add "everything else" rule to mod_rewrite

How can I make mod_rewrite redirect to a certain page or probably just throw 404 if no other rules have been satisfied? Here's what I have in my .htaccess file:
RewriteEngine on
RewriteRule ^\. / [F,QSA,L]
RewriteRule ^3rdparty(/.*)$ / [F,QSA,L]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^((images|upload)/.+|style.css)$ $1 [L]
RewriteRule ^$ special [QSA]
RewriteRule ^(special|ready|building|feedback)/?$ $1.php [QSA,L]
RewriteRule ^(ready|building)/(\d+)/?$ show_property.php?type=$1&property_id=$2 [QSA,L]
RewriteRule . error.php?code=404 [QSA,L]
This is supposed, among other things, to send user to error.php if he tries to access anything that was not explicitly specified here (by the way, what is the proper way to throw 404?). However, instead it sends user from every page to error.php. If I remove the last rule, everything else works.
What am I doing wrong?
What is happening is that when you are doing a rewrite, you then send the user to the new URL, where these rewrite rules are then evaluated again. Eventually no other redirectoin rules will be triggered and it will get to the final rule and always redirect to the error.php page.
So you need to put some rewrite conditions in place to make this not happen.
The rewrite engine loops, so you need to pasthrough successful rewrites before finally rewriting to error.php. Maybe something like:
RewriteCond %{REQUEST_URI} !^/$
RewriteCond %{REQUEST_URI} !^/(special|ready|building|feedback|show_property)\.php
RewriteCond %{REQUEST_URI} !^/((images|upload)/.+|style.css)$
RewriteRule ^ error.php?code=404 [QSA,L,R=404]
Each condition makes sure the URI isn't one of the ones your other rules have rewritten to.
The R=404 will redirect to the error.php page as a "404 Not Found".
Unfortunatelly, it didn't work - it allows access to all files on the server (presumably because all conditions need to be satisfied). I tried an alternate solution:
Something else must be slipping through, eventhough when I tested your rules plus these at the end in a blank htaccess file, it seems to work. Something else you can try which is a little less nice but since you don't actually redirect the browser anywhere, it would be hidden from clients.
You have a QSA flag at the end of all your rules, you could add a unique param to the query string after you've applied a rule, then just check against that. Example:
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^((images|upload)/.+|style.css)$ $1?_ok [L,QSA]
then at the end:
RewriteCond %{QUERY_STRING} !_ok
RewriteRule ^ error.php?code=404&_ok [QSA,L,R=404]
In theory if none of the rules are matched (and the requested URL does not exist), it's already a 404. So I think the simplest solution is to use an ErrorDocument, then rewrite it:
RewriteEngine On
ErrorDocument 404 /404.php
RewriteRule ^404.php$ error.php?code=404 [L]
# All your other rules here...
You can do the same for any other HTTP error code.
The problem here is that after the mod_rewrite finishes rewriting the URL, it is resubmitted to the mod_rewrite for another pass. So, the [L] flag only makes the rule last for the current pass. As much better explained in this question, mod_rewrite starting from Apache version 2.3.9, now supports another flag - [END], that makes the current mod_rewrite pass the last one. For Apache 2.2 a number of solutions are offered, but since one of them was a bit clumsy and another didn't work, my current solution is to add another two rules that allow a specific set of files to be accessed while sending 404 for everything else:
RewriteRule ^((images|upload)/.+|style.css|(special|ready|building|feedback|property).php)$ - [QSA,L]
RewriteRule .* - [QSA,L,R=404]
I think your last rule should be
RewriteRule ^(.*)$ error.php?code=404&query=$1 [QSA,L]
You could leave out the parenthesis and the $1 parameter, but maybe it's useful to know, what the user tried to achieve.
Hope, this does the trick!

mod_rewrite doesn't work both directions

I get an original url:
www.mydomain.com/menu/?myid=29&mypage=pizza-hut.html
with the following mod_rewrite code:
Options +FollowSymLinks
RewriteEngine on
RewriteRule ^menu/([^/]*)/([^/]*)\.html$ /menu/?pid=$1&alias=$2 [L]
I get this nice url:
www.mydomain.com/menu/29/pizza-hut.html
so, both url above reference the same page...right!
now the real deal is,
WHY when I type the url,the original one:
www.mydomain.com/menu/?myid=29&mypage=pizza-hut.html
it doesn't redirect to
www.mydomain.com/menu/29/pizza-hut.html
it keeps its original one in the address bar, is there any line I should add?
Essentially, all the links you generate should be the nice urls. Don't have links like /menu/?myid=29&mypage=pizza-hut.html in any of your pages. Use the clean URLs that you've ensured to route correctly on the back end that look like this: www.mydomain.com/menu/29/pizza-hut.html
The rules that you have rewrite on the server the nice looking urls to what your content understands (e.g. /menu/?myid=29&mypage=pizza-hut.html). That's the most important part. If you want to correct all the direct requests for the ugly URLs, you need to first make sure all your pages start using the nice looking ones, then you can maybe do something like this:
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /menu/?\?myid=([^&]+)&mypage=([^&\ ]+)
RewriteRule ^menu/?$ /menu/%1/%2? [R=301,L]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /menu/?\?myid=([^&]+)&mypage=([^&\ ]+)
RewriteRule ^menu/?$ /menu/%1/%2.\html? [R=301,L]
Note the ? following the .\html

.htaccess question - redirects after the domain name

Apologies if this is answered elsewhere. I had a search for this on here, but I'm quite confused so I'm not 100% what to search for in the first place.
I have a Wordpress site which is at exampledomain.com. I also own exampledomain.co.uk, and I have put in the .htaccess file the follow lines:
RewriteCond %{http_host} ^exampledomain.co.uk [nc]
RewriteRule ^(.*)$ http://exampledomain.com/$1 [r=301,nc]
These work fine in terms of changing exampledomain.co.uk to exampledomain.com, but the moment I add in something after the exampledomain.co.uk (i.e. exampledomain.co.uk/page1) the .htaccess file doesn't change it so it tries to load.
Is there something I can add to the .htaccess file which will sort this, so that, for example, if I were to type exampledomain.co.uk/page1 it would redirect to exampledomain.com/page1 ?
Thanks,
Charlie
P.S. Apologise for the weirdly parsed example links, but as a new user it won't let me include more than two hyperlinks.
Why not simply do
RedirectPermanent / http://exampledomain.com
in the co.uk's config instead? mod_rewrite is very handy, but for a simple domain redirector, it's major overkill.
comment followup:
I'd go for something like this:
RewriteCond %{HTTP_HOST} exampledomain.co.uk$ [NC]
RewriteRule (.*) http://exampledomain.com/$1 [R=301,L]

How do I make .htaccess do what I want? :) (appending query string to url)

Currently my .htaccess looks like this...
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ $1.php [L,QSA]
It currently changes any /xxx.php file into /xxx. This is great for SEO. However, I also want Mr. htaccess to convert certain URLs into a URL + query string. For instance when user goes to
/specific/somerandominfo
Then somerandominfo is passed to the specific.php file. I normally have no problem doing this using rewrites, but because of my fancy catchall rewrite, I can't figure out how to do it.
For example if I add
RewriteRule ^specific/([^/]+)$ /specific.php?somerandominfo=$1 [NC]
to my .htaccess, then hitting up /specific/somerandominfo just serves me a big fat 500 Internal Service Error.
Any help from you apache gurus out there would be so, so cool.
Thanks!
p.s. anybody want to also throw in any other cool SEO tricks that they like? I'll bake you cookies.
You are getting 500 error because your rules are creating an infinite cycle. Check apache error log to see if it is true. So you should design your rules properly. Maybe like that:
RewriteRule ^([^/]*)$ $1.php [L]
RewriteRule ^(.*)/(.*)$ $1.php?var=$2 [L]
RewriteRule ^specific/([^/]+)$ /specific.php?somerandominfo=$1 [NC]
This is mostly correct. I'd just add the B flag, like this:
RewriteRule ^specific/([^/]+)$ /specific.php?somerandominfo=$1 [NC,B]
This causes the capture group $1 to be properly escaped for use in query strings. Note that you can still use QSA to retain the query parameters used in the original request (in addition to somerandominfo).
Perhaps you'll want to post your actual RewriteRule.