rewrite url - remove trailing / if any and add .php

rewrite url - remove trailing / if any and add .php - .htaccess files are extremely useful in many cases for users who either do not have root permissions or for users who simply aren't comfortable in making changes in their web server's configuration file. Trying to debug .htaccess not working isn't always the easiest thing to do, however, hopefully by checking the discuss below mentioned about htaccess, url, mod-rewrite, url-rewriting, .htaccess common problems as well as the troubleshooting tips, you'll have a better grasp on what you may have to modify to get your .htaccess file running smoothly.Problem :


I have a simple question, yet I've found no posts that answer my question. I need an htaccess file that rewrites the urls so that it removes the ending / if any, and adds .php no matter what the folder it is in. Essentially, this is what I want to do:



http://example.com/login/ -> http://example.com/login.php
http://example.com/login -> http://example.com/login.php
http://example.com/user/test/login/ -> http://example.com/user/test/login.php
http://example.com/user/test/login -> http://example.com/user/test/login.php
http://example.com/$1/$2/$3/$4/ -> http://example.com/$1/$2/$3/$4.php
http://example.com/$1/$2/$3/$4 -> http://example.com/$1/$2/$3/$4.php
http://example.com/$1/$2/$3/ ... /$65/ -> http://example.com/$1/$2/$3/ ... /$65.php


I want it to rewrite the URL to remove the trailing slash if any, and add .php (but do this ONLY if the file exists). And it needs to have 'wildcard' support, meaning it works for all files without having to copy the code for each individual file. That way, the URLs 'look clean'.



I've found many posts with sample .htaccess files similar to what I want. But I haven't found one without one of these problems:




  1. It doesn't use 'wildcard' rewrites, so I would have to copy the code for each file to make it rewrite the URL


  2. It removes the trailing slash if any, then appends the filename to /index.php?file= instead of rewriting to the file.


  3. The 'wildcard' rewrite works only in the root directory. I can't use it if the files are nested like so: /$1/$2/$3/$4/.




Is this possible? I haven't seen anyone do it before.



Edit: I'll award a bounty if someone comes up with an .htaccess file that does all of this correctly, but also supports URL parameters.


Solution :

I assume you want to remove the trailing slash (if any) with an external redirect in order to canonicalise the URL and then append the .php extension with an internal rewrite (ie. hidden from the user) in order to correctly route the URL. This is a two-stage process.



NB: The trailing slash should remain if accessing a physical directory.



Using mod_rewrite in .htaccess:



RewriteEngine On

# Remove the trailing slash (if any) for non-directories
# This is essentially unconditional in order to canonicalise the URL
RewriteCond %REQUEST_FILENAME !-d
RewriteRule (.*)/$ /$1 [R=302,L]

# Append ".php" if that file would exist (internal rewrite / hidden from user)
RewriteCond %DOCUMENT_ROOT/$1.php -f
RewriteRule (.*) $1.php [L]


Change the R=302 (ie. temporary redirect) to R=301 to make it permanent. 302s are easier to test with as they aren't cached by the browser. (Make sure the browser cache is clear before testing.)



It is "wildcard" in the sense that it works for any file depth. .* simply grabs everything.



URL parameters will be appended onto the substitution by default - nothing special you need to do in this respect.








UPDATE: Since the canonical URL would seem to be the URL with the trailing slash (to which requests are being POST'd) then the above should be changed to the following:



RewriteEngine On

# Append .php if that file exists (internal rewrite)
RewriteCond %DOCUMENT_ROOT/$1.php -f
RewriteRule (.*?)/?$ $1.php [L]


This will accept requests for both /path/to/file and /path/to/file/ and internally rewrite the request to /path/to/file.php. You will need to handle the URL canonicalisation in your script. If all your URLs already point to /path/to/file/ (ie. with a trailing slash) then you can modify the RewriteRule pattern and remove both ? ie. (.*)/$ - this makes the trailing slash mandatory on the request.


Additionally, if you would like to do some further testing, give the htaccess tester tool a try. It allows you to specify a certain URL as well as the rules you would like to include and then shows which rules were tested, which ones met the criteria, and which ones were executed.

Comments

Popular posts from this blog

Rewrite in Mediawiki, remove index.php, .htaccess

.htaccess rewrite wildcard folder paths from host

Using .htaccess to set a cookie and 301 redirect