Reputation: 87
I am trying to redirect every php file to index.php except sitemap.xml. The problem is that sitemap.xml is redirected also to index.php. How to redirect all php files to index.php and sitemap.xml to sitemap.php ?
RewriteEngine On RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+)\ [NC] RewriteRule ^ %1 [R=301,L] RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} -f RewriteRule ^/?(.*)\.php$ index.php [L,QSA] RewriteRule sitemap.xml sitemap/sitemap.php [L]
Upvotes: 4
Views: 4165
Reputation: 45988
sitemap.xml
is being rewritten to sitemap/sitemap.php
, but then the rewriting process starts over (in .htaccess
) and sitemap/sitemap.php
then gets rewritten to index.php
on the second pass.
You should include an "exception" at the top of the file for any existing .php
file that you want to allow direct access. For example:
RewriteRule ^(index|sitemap/sitemap)\.php$ - [L]
This will prevent /index.php
and /sitemap/sitemap.php
from being processed by the directives that follow (and being rewritten to index.php
). index.php
currently "works" simply because mod_rewrite later detects you are writing back to itself and ignores the second rewrite.
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+)\ [NC] RewriteRule ^ %1 [R=301,L]
Aside: I'm not sure what this is supposed to be doing, but I don't think this is doing what you think it's doing? In fact, I don't think this is doing anything!? The trailing backslash (escape char) on the CondPattern is the concern here. It looks like you are trying to match the space after the request URL (and before the protocol), but that is not what is going to happen here, at the end of the CondPattern. The "problem" is that the space is also the argument delimiter in Apache config files. In order to match a space at the end of the pattern you should either use the \s
(any white-space character) shorthand character class, or enclose the CondPattern in double-quotes, or include the first few chars of the protocol (eg. HTTP
). For example:
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+)\s
RewriteCond %{THE_REQUEST} "^[A-Z]{3,}\s([^.]+) "
(escaping the space is optional if enclosed in double quotes)RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+)\ HTTP
The NC
flag is mostly superfluous unless you are trying to also catch invalid requests? Any legitimate browser request will have the method and protocol all uppercase.
However, if this did match (with the trailing space) then you would get a redirect loop for any URL that did not contain a .
(literal dot). So, either way, it does not look correct. (?)
Upvotes: 1
Reputation: 842
You need an additional RewriteCond to exclude sitemap.php, otherwise when sitemap.php is requested it will fulfill the two conditions !-d
and -f
and will again be rewritten to index.php
RewriteEngine On
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+)\ [NC]
RewriteRule ^ %1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} -f
RewriteCond %{REQUEST_FILENAME} !/(sitemap.php)/
RewriteRule ^/?(.*)\.php$ index.php [L,QSA]
RewriteRule sitemap.xml sitemap/sitemap.php [L]
Upvotes: 2