问题
I've got a RewriteMap
that looks like this:
Guide 1
Mini-Guide 2
White Paper 3
and I'm including it into Apache
via
RewriteMap legacy txt:/var/www/site/var/rewrite_map.txt
I want to create a RewriteRule
that will allow only values from the left side of said RewriteMap
to be in this position;
RewriteRule ^/section/downloads/(${legacy})/(.*)$ /blah.php?subsection=${legacy:%1}&title=$2
I know I can use ${legacy}
on the right side, but can I use it on the left, and if so, how?
回答1:
In your map file, the left side is the key and the right side is the value. When you create a rule for matching against a map, you input the key and it outputs the value.
Change your RewriteRule to this:
# Put these on one line
RewriteRule ^/section/downloads/([a-zA-Z-]+)/(.*)$
/blah.php?subsection=${legacy:$1}&title=$2
The first grouping captures the string in the incoming URL. The $1 in the replacement applies it to the named map. To make a default value, change ${legacy:$1}
to ${legacy:$1|Unknown}
.
Finally, if you only want the rule to work on values that are in the map file, add a RewriteCond
:
RewriteCond ${legacy:$1|Unknown} !Unknown
# Put these on one line
RewriteRule ^/section/downloads/([a-zA-Z-]+)/(.*)$
/blah.php?subsection=${legacy:$1}&title=$2
The condition says if the map does not return the default value (Unknown
), then run the next rule. Otherwise, skip the rule and move on.
Apache RewriteMap
回答2:
another variant:
# %1 will be the subpattern number1 afterwards
RewriteCond %{REQUEST_URI} ^/section/downloads/(.*)
# check if there is no mapping for %1
RewriteCond ${legacy:%1} !^$
# if there is rewrite it
RewriteRule ^/(.*) /blah.php?subsection=${legacy:%1}&title=$2 [R]
回答3:
You said, you want to only allow values found in the map. This isn't possible unless you specify an additional restriction in regex for the capture group. There's no way to do it with the map itself. There's no "map.keys" syntax, as far as I know, that you can apply in the left hand side, the pattern.
BUT,
You can specify a default value if the captured value is not found. This way:
## all on one line
RewriteRule ^/section/downloads/([a-zA-Z-]+)/(.*)$
/blah.php?subsection=${legacy:$1|defaultValue}&title=$2
Replace "defaultValue" with whatever you like. For example 0 (zero), or "notfound", if the given arg is not found in the map.
You can then either rewrite the result of that, with another rule, or just allow it to flow through and provide a "404" message at the URL with the default value.
If you choose to use another rule, then it would look like this:
## all on one line
RewriteRule ^/section/downloads/([a-zA-Z-]+)/(.*)$
/blah.php?subsection=${legacy:$1|notFoundMarker}&title=$2
## This rule fires if the lookupKey was not found in the map in the prior rule.
RewriteRule ^/blah.php?subsection=notFoundMarker /404.php [L]
来源:https://stackoverflow.com/questions/1909438/apache-rewriterule-with-rewritemap