Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I am currently using the following .htaccess file to remove the .php extension from my files and add a trailing slash to all URLs:

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^([^/]+)/$ $1.php

# Forces a trailing slash to be added
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !(\.[a-zA-Z0-9]{1,5}|/)$
RewriteRule (.*)$ /$1/ [R=301,L]

This is working great, however, when I have a php file in a directory, and I want to serve that file from a directory I get a 404 error. Is there a way to do this with 1 .htaccess file in the root. I really don't want to remember to put a .htaccess file in each directory.

Right now

Serves /information.php. Great! However

this throws a 404 even though the file /categories/category-1.php does exist. I would like to modify my .htaccess file so this serves /categories/category-1.php.

share|improve this question

migrated from Aug 4 '11 at 4:24

This question came from our site for professional and enthusiast programmers.

The regex pattern for first rewrite rule is the reason: ^([^/]+)/$ means any character EXCEPT slash /. Therefore it rejects anything that is located in sub folder.

You should use ^(.+)/$ pattern instead -- this will work for /information/ as well as /categories/category-1/ as well as /categories/category-1/hello-kitten/.

P.S. I would also add the L flag to stop matching further rules:

# add .php file extension
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*[^/])/?$ $1.php [L]
share|improve this answer
@Henry Wrinkler What error is that? Please check Apache's error log for details. – LazyOne Aug 2 '11 at 16:24
Ok, this works with one issue. If I navigate to It works. However, if I navigate to It throws a 500 error. I would be ok with this and just stop using the trailing slash rule, however, is there a way to get this to throw a proper 404 error instead of a 500 error? – Henry Wrinkler Aug 2 '11 at 16:39
@Henry Sorry .. I typed the answer .. then I could not access my Apache box (for some reason) to verify the code in real action, so I reverted it back. But now it is confirmed (see my updated rule): use this pattern ^(.*[^/])/?$ instead of ^(.+)$. This will work for both with and without trailing slash. If you want to ONLY work WITH slash, then remove ? from the pattern. – LazyOne Aug 2 '11 at 19:55
@Henry Wrinkler So .. did this worked for you? – LazyOne Aug 4 '11 at 1:20

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.