Forum Moderators: phranque
RewriteRule ^ - [E=PATTERN:foo|bar]
RewriteCond %{REQUEST_URI} ^/blah/?(?:%{ENV:PATTERN})?/?$ [NC]
RewriteRule ^blah/?(.*)/?$ /board/?topic=$1 [NC,QSA,L] RewriteCond %{REQUEST_URI} ^/blah/(?:%{ENV:PATTERN})?/?[a-z-]+/?$ [NC]
RewriteRule ^blah/(.*)/?([a-z-]+)/?$ /board/?topic=$1&p=$2 [NC,QSA,NE,L] RewriteCond %{REQUEST_URI} ^/blah/?(?:foo|bar)?/?$ [NC]
RewriteRule ^blah/?(.*)/?$ /board/?topic=$1 [NC,QSA,L] ^blah/(.*)/?([a-z-]+)/?$ /board/?topic=$1&p=$2 ^blah/(?:([^/]+)/)?([a-z-]+)/?$ /board/?topic=$1&p=$2--and not only because non-final .* or .+ should be avoided at almost any cost. Worse, this next line DOES match:
but it sends board/?topic=fo&p=o !
Is the idea that PATTERN is set to the string "foo|bar" and then mod_rewrite is supposed to interpret the | as a RegEx pipe?
$pattern = '#foo|bar#';
$result = preg_replace($pattern, 'blah', $string); As mentioned in your "other thread", you can't use variable expansion of the form %{VARIABLE} in any argument that expects a regex.
What is the reason behind separating out this subpattern?
# example.com/blah/foo
#-> board/?topic=foo
# example.com/blah
#-> board/?topic=
RewriteRule ^blah/?(foo|bar)?/?$ /board/?topic=$1 [NC,QSA,L]
# example.com/blah/foo/baseball-game/12345
#-> board/view/?topic=foo&id=12345
# example.com/blah/baseball-game/12345
#-> board/view/?topic=&id=12345
RewriteRule ^blah/(foo|bar)?/?[a-z-]+/([0-9]+)/?$ /board/view/?topic=$1&id=$2 [NC,QSA,NE,L]
# example.com/blah/foo/favorites
#-> board/?topic=foo&favorites=1
# example.com/blah/favorites
#-> board/?topic=&favorites=1
RewriteRule ^blah/(foo|bar)?/?favorites/?$ /board/?topic=$1&favorites=1 [NC,QSA,NE,L]
## this rule is for a legacy link
# example.com/blah/foo/search.php?search=baseball-game
#-> board/?topic=foo&p=baseball-game
# example.com/blah/search.php?search=baseball-game
#-> board/?topic=&p=baseball-game
RewriteRule ^blah/(foo|bar)?/?search.php /board/?topic=$1 [NC,QSA,L]
# example.com/blah/foo/baseball-game
#-> board/?topic=foo&p=baseball-game
# example.com/blah/baseball-game
#-> board/?topic=&p=baseball-game
RewriteRule ^blah/(foo|bar)?/?([a-z-]+)/?$ /board/?topic=$1&p=$2 [NC,QSA,NE,L] ## go ahead and set ?topic= but don't use [L], so the new variable is passed to the other rules
# example.com/blah/foo
# example.com/blah
RewriteRule ^blah/?(foo|bar)?/?(.*)$ /board/$2?topic=$1 [NC,QSA]
# example.com/blah/foo/baseball-game/12345
# example.com/blah/baseball-game/12345
#-> board/view/?topic=foo&id=12345
RewriteRule ^board/[a-z-]+/([0-9]+)/? /board/view/?id=$1 [NC,QSA,NE,L]
# example.com/blah/foo/favorites
# example.com/blah/favorites
#-> board/?topic=foo&favorites=1
RewriteRule ^board/favorites/?$ /board/?favorites=1 [NC,QSA,NE,L]
## this rule is for a legacy link
# example.com/blah/foo/search.php?search=baseball-game
# example.com/blah/search.php?search=baseball-game
#-> board/?topic=foo&p=baseball-game
RewriteRule ^board/search.php /board/ [NC,QSA,L]
# example.com/blah/foo/baseball-game
# example.com/blah/baseball-game
#-> board/?topic=foo&p=baseball-game
RewriteRule ^board/([a-z-]+)/?$ /board/?p=$1 [NC,QSA,NE,L]
The internal environment variables set by this directive are set after most early request processing directives are run, such as access control and URI-to-filename mapping. If the environment variable you're setting is meant as input into this early phase of processing such as the RewriteRule directive, you should instead set the environment variable with SetEnvIf.
This is showing a literal "$1" instead of the value of it:Where and how is it “showing” the environmental variable? Please say it isn’t on that same htaccess-testing site that I distrust so strongly.
RewriteRule ^([a-z]+)(?:/(.*)) /$2 [NC,E=VAR:$1]which on my test site turned into RewriteRule ^([a-z]+) - [E=test1:$1](initially I absent-mindedly left the $2, which created a server error). REDIRECT_ environment variables are created from the environment variables which existed prior to the redirect.
## first RewriteCond makes sure that VAR doesn't match an existing directory, so
## (foo|bar) is actually a list of every physical directory
## maybe I should do this instead?
# RewriteCond %{REQUEST_URI} !-f
# RewriteCond %{REQUEST_URI}/index\.php !-f
# RewriteCond %{REQUEST_URI} !-d
RewriteCond %{SCRIPT_NAME} !/(?:foo|bar) [NC]
RewriteCond %{QUERY_STRING} !(?:^|&)var=[a-z]+ [NC]
RewriteRule ^([a-z]+)(?:/(.+))?$ /$2?var=$1 [NC,E=VAR:$1,L] <?php print_r($GLOBALS); ?> RewriteRule ^ - [E=BLAH:boop]
That part makes sense, because if it were an external redirect
None of these will be set if the ErrorDocument target is an external redirect (anything starting with a scheme name like http:, even if it refers to the same host as the server).
For per-directory and htaccess rewrites, where the final substitution is processed as an internal redirect, environment variables from the previous round of rewriting are prefixed with "REDIRECT_".
if ($_SERVER['VAR'] || $_SERVER['REDIRECT_VAR']) { ... }
I don't think I'll need the <Directory> container...I was going to say that you may want to keep it for a handful of access-control rules that will be the same for all hostnames everywhere, without exception:
if ($_SERVER['VAR'] || $_SERVER['REDIRECT_VAR']) { ... }It may not even be necessary, based on what I’m seeing in logged headers: the REDIRECT_ version comes in addition to, not instead of the original version.
I would still have to modify all of the PHP scripts
If something would have to be changed in lots of places, now is the time to figure out how to shift it all into a single php include so it only has to be changed once, no matter how many scripts in how many different places use it.
That would be easy enough, I already have a variables scripts that I include on every PHP script, anyway. But I'd still have to change it in .htaccess or httpd.conf, too, so the "ideal" solution would be to set it as an environment variable.
To be honest, I don't really see why you need to add this additional layer of "validation"(?) in Apache config to begin with? This would seem to be just adding an additional layer of complexity/maintenance/potential bugs?
RewriteRule ^ - [E=TOPICS:foo|bar]
# if this link is an exact match, make this [L]
RewriteRule ^blah/(foo|bar)/?$ /blah/index.php?topic=$1 [NC,QSA,L]
# else, set ?topic= and continue on to other rules
RewriteRule ^blah/(foo|bar)(?:/(.+))?$ /blah/$2?topic=$1 [NC,QSA]
RewriteRule ^blah/[a-z-]+/(\d+)$ /blah/view/index.php?id=$1 [NC,QSA,L]
RewriteRule ^blah/favorites$ /blah/index.php?favorites=1 [NC,QSA,L]
RewriteRule ^blah/([a-z-]+)$ /blah/index.php?p=$1 [NC,QSA,L]