Search code examples
php.htaccessvanity-url

How-to? Vanity URL & ignore .PHP extension with .htaccess


I've got the following .htaccess working perfectly:

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule .* - [L]
RewriteRule ^(.*)$ http://www.mysite.com/mypage.php?u=$1 [NC]

This will allow me to write urls like this:

http://www.mysite.com/peter  =>  http://www.mysite.com/mypage.php?u=peter

But what if I want have an aditional rule to avoid writing the .php extension for existing files?

http://www.mysite.com/contact   (contact.php exists on file)

I tried adding this to my curr htaccess (but doesnt work):

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php

In other words, I would like to have vanity urls and ignore the .php extension in the same .htaccess.


SOLVED! Thanks to Ulrich Palha and Mario (didnt know about the ordering and the LAST [L] flag!

RewriteEngine on
# Unless directory, remove trailing slash
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/$ http://www.mysite.com/$1 [R=301,L]

# Redirect external .php requests to extensionless url
RewriteCond %{THE_REQUEST} ^(.+)\.php([#?][^\ ]*)?\ HTTP/
RewriteRule ^(.+)\.php$ http://www.mysite.com/$1 [R=301,L]

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php [L]

RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule .* - [L]
RewriteRule ^(.*)$ http://www.mysite.com/mypage.php?u=$1 [NC]

Solution

  • It's a matter of ordering. RewriteRules are applied in the order they are noted in the .htaccess
    See Everything You Ever Wanted to Know about Mod_Rewrite Rules but Were Afraid to Ask?

    Just add your new block as first rewrite statement, add a [LAST] flag, and it should work.

    This rule works unconditionally (not guarded by any RewriteCond), so should always be the last of all RewriteRules:

     RewriteRule ^(.*)$ ...
    

    (And all preceeding RewriteRules should preferrably carry a [L] flag. You have a bit of a workaround there.)