I've been working for hours in this and can't find information about it. Well yes, there is information, but I can only find separate solutions that don't work put toguether.
I'm trying to start from this:
RewriteCond %{REQUEST_URI} \.(php)$
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ http://www.example.com/$1/ [L,R=301]
The code works, I get the trailing slash. BUT if I put a non existing filename it returns a 301. For example:
http://www.example.com/thisfiledoesnotexist.php
The first header response is a 301, and it's logical, because it tries to return:
http://www.example.com/thisfiledoesnotexist.php/
And then it returns the 404, but this way it takes two requests to return a 404.
I supose that many people found this problem before, I believe it's a common issue, but I haven't found the solution to it.
Finally I got the solution!!! It's not simple, and I don't really understand how it works. I tried Adam Dimech's code, that can be found in this page.
The code is:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^([^/]+)/$ $1.php
RewriteCond %{THE_REQUEST} ^[A-Z]+\ /([^/]+/)*[^.]+\.php(\?[^\ ]*)?\ HTTP/
RewriteRule ^(([^/]+/)*[^.]+)\.php$ http://www.example.com/yourdirectory/$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !(\.[a-zA-Z0-9]{1,5}|/)$
RewriteRule (.*)$ http://www.example.com/yourdirectory/$1/ [R=301,L]
This code has to be put in each directory where we will be working with. If you use relative paths you have to use
The code worked fantastic. Now I can take off the php extension and force the trailing slash. Hope it's useful for more people!