JakeGriffin
JakeGriffin

Reputation: 223

.htaccess - force www, trailing slash and remove extension

I've been playing about with my .htaccess file and so far, it's working, but there's a few bugs.

I'm trying to force the WWW prefix (just the root, not on subdomains) while removing the .php extension and adding a trailing slash.

Code

# Force WWW prefix
RewriteCond %{HTTP_HOST} !^$
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTPS}s ^on(s)|
RewriteRule ^ http%1://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]


# Remove .php extension
RewriteCond %{THE_REQUEST} ^GET\ /[^?\s]+\.php
RewriteRule (.*)\.php$ /$1/ [L,R=301]

RewriteRule (.*)/$ $1.php [L]


# Force trailing slash
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule .*[^/]$ $0/ [L,R=301]

It successfully force the WWW, even if I remove it, the .php extension is removed, even if I add it, and the the trailing slash is forced, even if I remove it. However, sometimes I get a 404 not found error saying that the requested URL (generally ending with the .php extension) was not found on the server, and often directories do not actually work. Edit

often directories do not actually work

meaning the server throws a 404 error saying "/directory.php was not found on this server".

Can anyone lend me a hand?

Upvotes: 2

Views: 5360

Answers (1)

Jon Lin
Jon Lin

Reputation: 143856

You need to check that you're actually rewriting to a php file before you blindly attach the php extension. So this rule:

RewriteRule (.*)/$ $1.php [L]

Needs some conditions:

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

You can also avoid redirecting to include www in the hostname for subdomains if you check that there is at least 1 host before the TLD, try adding another condition to your prefix rule:

# Force WWW prefix
RewriteCond %{HTTP_HOST} !^$
RewriteCond %{HTTP_HOST} ^([^.]+)\.([a-z]{2,4})$ [NC]
RewriteCond %{HTTPS}s ^on(s)|
RewriteRule ^ http%1://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

EDIT:

Here's what the full file should look like:

RewriteBase /

# Force WWW prefix
RewriteCond %{HTTP_HOST} !^$
RewriteCond %{HTTP_HOST} ^([^.]+)\.([a-z]{2,4})$ [NC]
RewriteCond %{HTTPS}s ^on(s)|
RewriteRule ^ http%1://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]


# Remove .php extension
RewriteCond %{THE_REQUEST} ^GET\ /[^?\s]+\.php
RewriteRule (.*)\.php$ /$1/ [L,R=301]

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


# Force trailing slash
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule .*[^/]$ $0/ [L,R=301]

Upvotes: 7

Related Questions