Home > Software engineering >  File .htaccess not working with URL that has a dash and 2nd RewriteRule not applied
File .htaccess not working with URL that has a dash and 2nd RewriteRule not applied

Time:05-28

I have a problem with .htaccess file, as I understand RewriteRule help to rewrite the 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?

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 to 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.

  • Related