Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use Apache Mod_rewrite to remove php extension, while preserving the GET parameters?

I was trying to remove the PHP extensions from my website. When user requests a PHP file, the PHP will be removed and the user will be redirected, and when the user types in an URL without PHP, the actual PHP file will be served. This worked well except when there is GET parameter in the URL. My rules are as below:

# remove .php ONLY if requested directly
RewriteCond %{THE_REQUEST} (\.php\sHTTP/1)
RewriteRule ^(.+)\.php$ /$1 [R=301,L,QSA]

# remove trailing slash ONLY if it is not an existing folder
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]

# rewrite to FILENAME.php if such file does exist and is not a folder
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ /$1.php [L,QSA]

I thought this should already be able to remove php even when there is any GET parameter, but it failed. I also tried something like this:

RewriteCond %{THE_REQUEST} (\.php\sHTTP/1)
RewriteRule ^(.)\.php(.)$ $1$2 [R=301,L,QSA]

It also didn't work, the php is still there. But if I try:

RewriteRule ^(.)\.php(.)$ $1$2 [R=301,L,QSA]

ie, removing the RewriteCond, the php extension gets removed and the parameters were preserved, but the page won't be served as the browser says there were too many redirects.

Anyone any ideas please?

like image 899
Xavier Avatar asked Nov 03 '22 17:11

Xavier


1 Answers

Thank you SteAp for your answer. I happened to be able to figure out a way to deal with it just now, and would like to share here in case others run into similar problems.

In my rules, I have

# remove .php ONLY if requested directly
RewriteCond %{THE_REQUEST} (\.php\sHTTP/1)
RewriteRule ^(.+)\.php$ /$1 [R=301,L,QSA]

To execute external redirect when user requests a PHP file. The RewriteCond here is to prevent redirect loops - ie, endless redirect due to improper internal rewrite and external redirect (removing php, then adding php, then remove again, ...)

When there are parameters, the actual header comes as http://domain.com/file.php?.... HTTP/1.1 Something like this, so the pattern in the RewriteCond won't work since it didn't take parameters into account.

To solve it, simply replace the above code with:

# remove .php ONLY if requested directly
RewriteCond %{THE_REQUEST} (\.php(.*)\sHTTP/1)
RewriteRule ^(.+)\.php$ /$1 [R=301,L,QSA]

By doing so, the parameters can be matched by the pattern, and now everything works.

Hope this will help someone having similar problem (or is it just a noob like me? lol)

like image 145
Xavier Avatar answered Nov 15 '22 06:11

Xavier