Here\'s what I got so far. The first part works but not the redirect itself.
What do I need to do to make it work?
RewriteEngine On
RewriteRule ^([^/\\.
Besides the first rule overriding the second one, your second rule also won't work because you're trying to match the query string in a RewriteRule. Try something like this instead:
RewriteEngine On
RewriteBase /
RewriteCond %{QUERY_STRING} ^name=([^/.&]+)/?$
RewriteCond %{ENV:REDIRECT_LOOP} !1
RewriteRule ^page\.php$ /%1? [NS,R=301,L]
RewriteRule ^([^/.]+)/?$ page.php?name=$1 [NS,QSA,E=LOOP:1]
(I included the QSA flag so that an URL like /foobar?foo=bar
will be rewritten to /page.php?name=foobar&foo=bar
instead of just /page.php?name=foobar
. If you don't want that, leave it out.)
Note: The second RewriteCond
is there to keep the first rule from matching again after the second one has matched. The problem is that, in .htaccess context, mod_rewrite acts more or less as if all rules had the PT flag, causing the ruleset to be rerun from the start after every rewrite, even internal ones. Or, to quote the documentation:
"If you are using RewriteRule in either .htaccess files or in
sections, it is important to have some understanding of how the rules are processed. The simplified form of this is that once the rules have been processed, the rewritten request is handed back to the URL parsing engine to do what it may with it. It is possible that as the rewritten request is handled, the .htaccess file or section may be encountered again, and thus the ruleset may be run again from the start. Most commonly this will happen if one of the rules causes a redirect - either internal or external - causing the request process to start over."
The workaround I'm using is to set a custom environment variable with E=LOOP:1
when the internal rewrite triggers, and check for it before doing the external rewrite. Note that, when the request processing restarts after the internal rewrite, Apache prepends REDIRECT_
to the names of all environment variables set during the previous pass, so even though the variable we set is named just LOOP
, the one we need to check for is REDIRECT_LOOP
.