Can anyone please review the following .htaccess file and let me if it is correctly put together?

What I think it does:

  • So it direct to a custom 404 page
  • Remove the extensions from the end of the urls (example .php)
  • Remove /index
  • I don't really understand what the final rule does, can anyone please explain it if could?
DirectoryIndex index.html index.php 
ErrorDocument 404 /404 

RewriteEngine On 
RewriteBase / 

# Remove enter code here.php; use THE_REQUEST to prevent infinite loops 
# By puting the L-flag here, the request gets redirected immediately 
RewriteCond %{THE_REQUEST} ^GET\ (.*)\.php\ HTTP 
RewriteRule (.*)\.php$ $1 [R=301,L] 

# Remove /index 
# By puting the L-flag here, the request gets redirected immediately 
# The trailing slash is removed in a next request, so be efficient and dont put it on there at all 
RewriteRule (.*)/index$ $1 [R=301,L] 

# Remove slash if not directory 
# By puting the L-flag here, the request gets redirected immediately 
RewriteCond %{REQUEST_FILENAME} !-d 
RewriteCond %{REQUEST_URI} /$ 
RewriteRule (.*)/ $1 [R=301,L] 

# Add .php to access file, but don't redirect 
# On some hosts RewriteCond %{REQUEST_FILENAME}.php -f will be true, even if 
# no such file exists. Be safe and add an extra condition 
# There is no point in escaping a dot in a string 
RewriteCond %{REQUEST_FILENAME}.php -f 
RewriteCond %{REQUEST_URI} !(/|\.php)$ 
RewriteRule (.*) $1.php [L]
  • \$\begingroup\$ in order for your custom error page to be directed properly you need to put a URL after it and remove the duplicate 404 ie ErrorDocument 404 https://www.youdomain.something/errorpage.php \$\endgroup\$
    – Ryan Stone
    Jul 22, 2019 at 5:02

1 Answer 1


This is basically a canonicalizing URL prettifier that redirects clients to a shorter URL.

The RewriteCond operating on %{THE_REQUEST} is weird, since it works directly at the HTTP protocol level. I understand that you want to avoid redirecting POSTs, since a redirect would convert POSTs into GETs, and such breakage would be an unacceptable consequence for having nicer-looking URLs. However, it would be better to test %{REQUEST_METHOD} instead.

In the worst case, you could end up redirecting the client three times:

  1. GET /path/to/directory/index.php/:
  2. GET /path/to/something/index.php
  3. GET /path/to/something/index
  4. GET /path/to/something

By combining the first two rules, you could eliminate the third request.

# Strip off /index.php or /index or .php
RewriteRule (.*)(/index\.php|/index|\.php)$ $1 [R=301,L]

In the trailing slash cleanup, you have a superfluous RewriteCond:

# Remove slash if not directory 
RewriteCond %{REQUEST_FILENAME} !-d 
RewriteRule (.*)/$ $1 [R=301,L]

I would tweak your last rule a bit. Do the string analysis check before the filesystem check. Use $0 instead of %{REQUEST_URI} and $1.

RewriteCond $0 !(/|\.php)$
RewriteCond %{REQUEST_FILENAME}.php -f 
RewriteRule .* $0.php
  • \$\begingroup\$ Can you please show me how it would look like all put together? I have tried to put them together but I am confused - I really don't know what I am doing \$\endgroup\$
    – Leo
    Feb 2, 2014 at 23:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.