Forum Moderators: phranque

Message Too Old, No Replies

rewriterule ordering problems

         

justicewhite

10:10 pm on May 14, 2005 (gmt 0)

10+ Year Member



Hi,

I'm having trouble with the following 2 rules:

RewriteRule listing_browse/(.*)/(.*)/(.*)/(.*)/(.*)/(.*)/(.*)/$ /listing_browse.php?Branch[]=$1&Branch[]=$2&type[]=$3&$4=$5&$6=$7 [L]

RewriteRule listing_browse/(.*)/(.*)/(.*)/(.*)/(.*)/(.*)/(.*)/$ /listing_browse.php?type[]=$1&$2=$3&$4=$5&$6=$7 [L]

Whicheverone I seem to have above seems to catch both scenarios.

Here are how the URLs look:

[mydomain.com...]

and

[mydomain.com...]

Your help would be appreciated...

jdMorgan

11:54 pm on May 14, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



justicewhite,

Welcome to WebmasterWorld!

There is nothing different between the two RewriteRule patterns you have posted, so there is no "information" in the requested URL to differentiate the two requests by using pattern-matching. Therefore, as posted, your problem is impossible to solve.

Your rule patterns are also coded in the least-efficient possible way; Each pattern will need to be processed 28 times in order to resolve a match (if I counted right). This won't solve your basic problem, but a much better way to code these rules would be something like:


RewriteRule listing_browse/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/?$ /listing_browse.php?Branch[]=$1&Branch[]=$2&type[]=$3&$4=$5&$6=$7 [L]

This pattern can be evaluated in one pass, proceeding strictly from left to right, without recursive evaluation.

To get a better answer, it will be helpful if you tell us more about what you are trying to accomplish with these rules -- what is your goal?

Jim

justicewhite

2:24 pm on May 15, 2005 (gmt 0)

10+ Year Member



Hi Jim,

Thanks for your quick response.

The difference is that for one of them, the QUERY_STRING starts with Branch[]=

and for the other one it starts with type[]=

I tried a lot of combinations with RewriteCond all day yesterday without much joy.

You may be quite right about the efficiency of this statement. I got it to this stage by trial and error :)

Unfortunately, I couldn't find much detailed info on the net about the RewriteRule stuff. There are lots of copies of the Apache documentation but not specific, detailed examples.

Is the efficiency because of trying to match every single char in my current use? I would be greatful if you can elaborate a little further on this.

Thanks again...

jdMorgan

4:09 pm on May 15, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



The problem is that the 'difference' must be in the URL that RewriteRule tests -- the one matched by the pattern on the left side of the rule, and the one requested by the client browser. There is no difference between your two rule patterns.

Again, what are you trying to do with this? If you are trying to use search-engine-friendly static URLs, and then use mod-rewrite to convert requests for those URLs into dynamic-URL calls to your script, then the 'friendly' URL requested from your server must carry sufficient information to re-construct the dynamic URL.

For example, you could use two different 'friendly' URL formats, one of "browse" and one of "type." This would provide enough information to rebuild the query string.

I could go on speculating as to your application and various solutions, but I'm guessing.

The use of multiple ".*" patterns in a rule is inefficient because ".*" matches as many characters as possible on each trial match. So, the first time through, mod_rewrite tries to match all characters in the URL into the first ".*" it finds. This will fail, because there is then no more URL to match into the subsequent subpatterns. So it then has to repetetively "back off" one character at a time from the end of the requested URL, trying again and again to match the whole pattern by starting to compare from the left end. This results in a large number of trial matches, both within and among the multiple ".*" subpatterns.

By using "[^/]+" instead of ".*", you explicitly tell mod_rewrite to stop matching inside each subpattern as soon as it finds a slash. This allows the the whole pattern to be unambiguously matched in one trial, starting from the left and proceeding to the right. It can be hundreds of times faster.

Jim

justicewhite

6:01 pm on May 15, 2005 (gmt 0)

10+ Year Member



Hi Jim,

Thanks for your reply again. The efficiency bit makes more sense now.

As for the reason why I'm trying to do this; your assumption is correct. I'm trying to present the URLs in s spider friendly format.

I still don't understand that "difference" point though.

Do you mean that the [mydomain.com...] part needs to be different?

Or more probably, the RewriteRule listing_browse/(.*)/(.*)/(.*)/(.*)/(.*)/(.*)/(.*)/$ bit needs to be different. Is this correct?

I'll get down to work.

Thanks again, your help has really been appreciated...

jdMorgan

7:58 pm on May 15, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



The "friendly URLs" you put on your pages --the ones that the vicitor will click on-- must contain sufficient information to reconstruct the 'real' URLs -- the dynamic ones used to call your script after the rewrite.

The friendly URL is what mod_rewrite will receive from the client, and attempt to match to the pattern on the left side of the rule. As it stands now, it appears that all friendly URLs look like this:

http://www.example.com/listing_browse/u/v/w/x/y/z/

This can match either of the identical patterns in your two rules. As a result, whichever rule you put first in your .htaccess file will match the request, and the other rule will never be applied. The information needed to discern which of the two rules to apply is not present in the requested URL.

So, you need to add that information in some way. An example would be to use the two 'friendly' URLs:

http://www.example.com/listing_browse_branch/u/v/w/x/y/z/
http://www.example.com/listing_browse_type/u/v/w/x/y/z/

or maybe

http://www.example.com/listing_browse/br/u/v/w/x/y/z/
http://www.example.com/listing_browse/ty/u/v/w/x/y/z/

or even

http://www.example.com/br-list/u/v/w/x/y/z/
http://www.example.com/ty-list/u/v/w/x/y/z/

Just as long as the requested URLs contain the unique information in any form.

Basically, even though it sounds like an academic discussion, the best way to describe it is that it is a "missing-information problem" -- mod_rewrite cannot create information, it can only rearrange and/or reformat the information it receives from the browser. The friendly URL must contain sufficient information to tell mod_rewrite which rule to apply.

Here's how the whole process works, assuming that you started with a site using dynamic URLs:

Site modification:

  • Change the on-page links to static "friendly" URLs -- either hand-coding them or using php preg_replace, etc. to modify database info to create the link.
  • Write mod_rewrite rules to convert these "friendly" URLs back to the dynamic form needed to run your script.

    Access:

  • Visitors and search engine robots now 'see' friendly URLs and request them.
  • Friendly URL request arrives at your server.
  • mod_rewrite changes requested URL to correct dynamic format and calls your script.
  • Script produces a new page, and the process repeats.

    I hope this is clearer. It's sometimes a difficult conceptual hill to surmount.

    Jim

  • justicewhite

    8:32 am on May 16, 2005 (gmt 0)

    10+ Year Member



    That is fantastic Jim. It is now cristal clear :)

    Thanks again for your help...