0

I have in my .htaccess the following code:

RewriteEngine On
RewriteRule ^/?([^/\.]+)/?$ $1.php [L]
RewriteRule ^/?([^/\.]+).php$ $1/ [R,L]

RewriteRule ^/?([^/\.]+)/?$ $1.php [L] is working fine. What this is doing is taking a url like http://www.example.com/whatever and making it read the page as http://www.example.com/whatever.php.

However, what I'd like to be able to do is take a url like http://www.example.com/whatever.php and automatically send it to http://www.example.com/whatever, hence the second line of the code. However, this isn't working. What its doing now, is as soon as it comes across a link ending in .php, the url becomes http://localhost/C:/Sites/page/whatever/, and pulling a 403: Forbidden page.

All I want to know is what I can to so that http://www.example.com/whatever.php will be read as http://www.example.com/whatever, and that if http://www.example.com/whatever.php is entered into the URL bar, it will automatically redirect to http://www.example.com/whatever.

Does that make any sense?

EDIT

Ok, so it appears I wasn't all too clear.. basically, I want /whatever/ to read as whatever.php while the URL still stays as /whatever/, right? However, if the URL was /whatever.php, I want it to actually redirect the users URL to /whatever/, and then once again read it as whatever.php. Is this possible?

Connor Deckers
  • 2,447
  • 4
  • 26
  • 45

2 Answers2

1

If you're rules are inside an .htaccess file, you can omit the leading slash when you match against a URI:

RewriteRule ^([^/\.]+)/?$ /$1.php [L]

Also note that a leading slash is included in the target (/$1.php), this makes sure /whatever/ gets rewritten to /whatever.php. When you redirect, if you are missing this leading slash, apache prepends the document root to it. Thus /whatever.php gets redirected to the document root C:/Sites/page/whatever/. Even if you include the leading slash, this will never work because you're going to cause a redirect loop:

  1. Enter "http://www.example.com/whatever.php" in your address bar
  2. apache redirects you to "http://www.example.com/whatever/"
  3. apache gets the URI whatever/ and applies the first rule and the URI gets rewritten to /whatever.php
  4. The URI gets put through the rewrite engine again
  5. the URI /whatever.php matches the second rule and redirects the browser to "http://www.example.com/whatever/"
  6. repeat steps 3-5

You need to add a condition that the actual request is for /whatever.php:

RewriteCond %{THE_REQUEST} ^(GET|POST|HEAD)\ /([^/\.]+)\.php
RewriteRule ^ /%2/ [R,L]

So altogether, you'll have:

RewriteEngine On
RewriteRule ^([^/\.]+)/?$ /$1.php [L]
RewriteCond %{THE_REQUEST} ^(GET|POST|HEAD)\ /([^/\.]+)\.php
RewriteRule ^ /%2/ [R,L]
Jon Lin
  • 142,182
  • 29
  • 220
  • 220
  • Thanks Jon! I tried this code earlier, and it didn't seem to work, but I tried it again this morning, and what do you know, it works! It appears my `.htaccess` was simply having a moment.. still, thank you very much for this! – Connor Deckers Mar 11 '12 at 22:10
0

You're making a relative path substitution in a per-directory context (.htaccess is a per-directory context). This requires RewriteBase. Per-directory rewrites are done in a later stage of processing, when URLs have been mapped to paths. But the rewrite must produce a URL, which is processed again. I think without the RewriteBase to supply the URL prefix, you end up with a filesystem prefix instead of the URL. That may be why you're getting the C:/Sites thing. Try RewriteBase. But after a correct RewriteBase to specify the correct URL prefix to be tacked in front to the relative rewritten part, I'm afraid you will have the rewrite loop, because you're rewriting whatever.php to whatever; and whatever to whatever.php.

Reference: http://httpd.apache.org/docs/current/rewrite/tech.html

Kaz
  • 55,781
  • 9
  • 100
  • 149
  • Cheers Kaz, I think this could make a big difference. However, I'm not _redirecting_ `whatever` to `whatever.php` so much, I thought, as just telling it when it sees `whatever`, to draw information from `whatever.php`. Is there any way I can do it so that if it sees `whatever` it will draw from `whatever.php`, but the url will still show `whatever`, but if the url is `whatever.php`, it will redirect to `whatever`? – Connor Deckers Mar 10 '12 at 06:32