问题
At the moment, I have a simple .htaccess that tidies up my page urls, by knocking the .php off the end, or adding it, depending on which way you look at it.
Basically, /about.php will become /about.
However, this results in my page being accessible on both of those urls. I can just suck it up and use rel=canonical tags but I'd also like to tidy it in my htaccess.
Is there a better way (clever rule) to 301 the .php to the none .php version, other than manually specifying each url?
Also, do I really need those rewritecond rules?
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*)$ /$1.php [QSA,L]
ErrorDocument 404 /404
</IfModule>
回答1:
In you original rules, you are just saying that any page that is not a file or a directory has to be redirected to the same name with .php
appended.
So what you need to do to "remove" access to the .php
file is to mask it with a redirection.
So you will tell the client browser that foo/foo.php
is in fact foo/foo
.
This will trigger a new request to foo/foo
by the client.
Then you tell the server that foo/foo
is in fact foo/foo.php
. This will trigger an internal request to foo/foo.php
. So here you have a loop. We need to avoid that. The best workaround I've found is to check wethere the %{REDIRECT_URL}
is empty or not.
Finally rules are :
# External redirection from real file to virtual with safe guard for internal redirection.
RewriteCond %{REQUEST_FILENAME} -f
RewriteCond %{REDIRECT_URL} !^$
RewriteRule ^(.*)\.php$ /$1 [QSA,R=301,L]
# Internal redirection to real file.
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*)$ /$1.php [QSA,L]
Do not forget that ANY rewrite/redirection triggers a new request!
See : How does url rewrite works?
回答2:
To redirect (301) each .php-URL to the non-.php version (in case it's an existing file) you could use this one:
RewriteCond %{REQUEST_FILENAME} -f
RewriteCond %{THE_REQUEST} \.php\ HTTP/.\..$
RewriteRule ^(.*)\.php$ /$1 [QSA,R=301,L]
The first two RewriteCond in your .haccess are not really required, because you will have some conflicts anyway, e.g. if you have a file foo.htm
and foo.htm.php
, which one should be shown when foo.htm
is requested?
So the complete mod_rewrite
block:
RewriteEngine On
# redirect /foo.php to /foo
RewriteCond %{REQUEST_FILENAME} -f
RewriteCond %{THE_REQUEST} \.php\ HTTP/.\..$
RewriteRule ^(.*)\.php$ /$1 [QSA,R=301,L]
# rewrite /foo to /foo.php
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*)$ /$1.php [QSA,L]
来源:https://stackoverflow.com/questions/6520404/avoiding-duplicate-urls-wih-my-mod-write