I am self learning php and have problem with .htaccess file, as I understand rewriterule help to rewrite url. But when I try the following 2 cases it doesn't work.
#1 The first Rewriterule works but the second doesn't work
RewriteRule ^([a-zA-Z0-9_-] )$ index.php?idcat=$1 [L] #working
RewriteRule ^([a-zA-Z0-9_-] )$ index.php?idl=$1 [L] #not working
#2 The Rewriterule doesn't work with dash but works with slash and underscore.
RewriteRule ^([a-zA-Z0-9_-] )-([a-zA-Z0-9_-] )$ index.php?idl=$1&iddis=$2 [L] #not working
RewriteRule ^([a-zA-Z0-9_-] )_([a-zA-Z0-9_-] )$ index.php?idl=$1&iddis=$2 [L] #working
RewriteRule ^([a-zA-Z0-9_-] )/([a-zA-Z0-9_-] )$ index.php?idl=$1&iddis=$2 [L] #working
So how to fix these problems? Does anyone have any suggestions for me? Any suggestions are appreciated!
Thanks so much!
CodePudding user response:
#1 The first Rewriterule works but the second doesn't work
RewriteRule ^([a-zA-Z0-9_-] )$ index.php?idcat=$1 [L] #working RewriteRule ^([a-zA-Z0-9_-] )$ index.php?idl=$1 [L] #not working
Because you are using the same pattern in both rules, the first rule always "wins" and the second rule is never triggered. This is essentially processed as follows (pseudo-code):
if (the URL matches the pattern "^([a-zA-Z0-9_-] )$") {
rewrite the request to "index.php?idcat=<url>"
}
elseif (the URL matches the pattern "^([a-zA-Z0-9_-] )$") {
rewrite the request to "index.php?idl=<url>"
}
As you can see, the second code block is never processed since the expressions are the same.
To put it another way, how would you determine whether a request of the form /foo
should be rewritten to index.php?idcat=foo
or to index.php?idl=foo
? You can't rewrite the request to both.
In this particular case you could perhaps rewrite everything to index.php?id=<url>
and let your script decide whether it should be idcat
or idl
. Otherwise, there needs to be something different about the two URLs (and consequently the patterns you are using to match the URLs) that allows you
determine how the URL should be rewritten.
#2 The Rewriterule doesn't work with dash but works with slash and underscore.
RewriteRule ^([a-zA-Z0-9_-] )-([a-zA-Z0-9_-] )$ index.php?idl=$1&iddis=$2 [L] #not working RewriteRule ^([a-zA-Z0-9_-] )_([a-zA-Z0-9_-] )$ index.php?idl=$1&iddis=$2 [L] #working
Both these rules have the same problem, depending on the URLs being requested. This is because the patterns/regex you are using are "ambiguous". Each of the two subpatterns (either side of the delimiter), that are used to match the idl
and iddis
values, contain the same character as the expected delimiter, -
or _
. However, in the 3rd rule (not shown), you are using a /
as the delimiter, which does not occur in the surrounding subpatterns, so there is no ambiguity,
For example, how should (or you would expect) a URL of the form /foo-bar-baz
to be matched by the first rule? Since the first subpattern uses the greedy quantifier
, it will capture foo-bar
and baz
and rewrite the request to index.php?idl=foo-bar&iddis=baz
.
To avoid this "ambiguity" you need to make sure the delimiter between the subpatterns (ie. between the values for idl
and iddis
) is different to the characters used in the subpatterns (or at least one of the two subpatterns).
This can often be resolved by making the regex as specific as possible. ie. Match only the valid characters in idl
and iddis
.
To begin resolving this issue, you need to first identify the precise URLs you are trying to match, before implementing the rules to match them.