mod_rewrite to remove .php but still serve the .php file? mod_rewrite to remove .php but still serve the .php file? apache apache

mod_rewrite to remove .php but still serve the .php file?


For this solution, I have followed the following rules:

  1. If the user tries to load /something.php they should be externally redirected to /something.
  2. If the user tries to load /something then they should be internally redirected to /something.php.
  3. If the user passed any query string parameters to the URL then these should be preserved through the redirects.
  4. If the user tries to load a different file which really exists on the filesystem (a stylesheet, image etc) then this should be loaded as is.

And here's the final set of mod_rewrite magic:

RewriteEngine onRewriteBase /## Always use www.RewriteCond %{HTTP_HOST} ^mysite\.com$ [NC]RewriteRule ^(.*)$ http://www.mysite.com/$1 [L,R=301]# Change urlpath.php to urlpath## Only perform this rule if we're on the expected domainRewriteCond %{HTTP_HOST} ^www\.mysite\.com$ [NC]## Don't perform this rule if we've already been redirected internallyRewriteCond %{QUERY_STRING} !internal=1 [NC]## Redirect the user externally to the non PHP URLRewriteRule ^(.*)\.php$ $1 [L,R=301]# if the user requests /something we need to serve the php version if it exists## Only perform this rule if we're on the expected domainRewriteCond %{HTTP_HOST} ^www\.mysite\.com$ [NC]## Perform this rule only if a file with this name does not existRewriteCond %{REQUEST_FILENAME} !-f## Perform this rule if the requested file doesn't end with '.php'RewriteCond %{REQUEST_FILENAME} !\.php$ [NC]## Only perform this rule if we're not requesting the index pageRewriteCond %{REQUEST_URI} !^/$## Finally, rewrite the URL internally, passing through the user's query string## using the [qsa] flag along with an 'internal=1' identifier so that our first## RewriteRule knows we've already redirected once.RewriteRule ^(.*)$ $1.php?internal=1 [L, QSA]


Your third rule should be the other way around:

# Change urlpath.php to urlpathRewriteCond %{HTTP_HOST} ^www\.mysite\.com$ [NC]RewriteCond %{REQUEST_FILENAME} !\.php$ [NC]RewriteRule ^/?(.*)$ $1.php [L,R=301]

Once the user goes to /contact, it'll load contact.php. The extra RewriteCond is so that if people DO go to contact.php, it won't try to load contact.php.php


As I understand you want the URL to be /contact even if the URL was /contact.php.

You can check for the .php extension and do a redirect to remove it. Use R=301 (as you do).

Then you have to make your server accept the URL without the .php extension. It might actually already do that.

That's what mod_negotiation does. It should be installed by default, but you might have to enable it.

You can also do that with mod_rewrite, but remove the R from the options. It will redirect internally instead of answering with an HTTP redirect.