Forum Moderators: phranque

Message Too Old, No Replies

Mod Rewrite and Calculations

Is it possible to add values with apache mod_rewrite?

         

jepler

5:17 pm on Mar 13, 2008 (gmt 0)

10+ Year Member



Not sure if this is possible, but thought I'd ask anyway. Can you use mod rewrite to sum integers?

For instance, I'd like to add +1 to the back-reference so the final value is always plus one (+1) to what is stored in the original range. I tried the following but it didn't work.


RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /page\.php\?pageNumber=([^&]+)\ HTTP/
RewriteRule ^page\.php$ http://www.example.com/page%1+1.php? [R=301,L]

outputs...
http://www.example.com/page1+1.php

but I'd like it to read..
http://www.example.com/page2.php

Thanks,

-Jim

[edited by: jdMorgan at 3:17 am (utc) on Mar. 14, 2008]
[edit reason] example.com [/edit]

jdMorgan

9:21 pm on Mar 13, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



No, you can't do math with mod_rewrite. It's a limited-application module with a fixed "instruction set" and it works only with text strings, not numeric values.

However, you can use some tricks to do lookups -- IF the range of the numbers is not large -- say less than 20.

If the range is large and you have httpd.conf access, you can define a RewriteMap to call a script (e.g. PERL) to calculate the value.

So how large is your range?

Jim

jepler

1:10 pm on Mar 14, 2008 (gmt 0)

10+ Year Member



Thanks. Range of numbers isn't too large, between 3 and 15.

jdMorgan

3:19 am on Mar 15, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



OK, then here's an example of a lookup-table method:

RewriteCond %{QUERY_STRING} ^pageNumber=[0-9]+$
RewriteCond %{QUERY_STRING}<>4 ^pageNumber=3<>(.+)$ [OR]
RewriteCond %{QUERY_STRING}<>5 ^pageNumber=4<>(.+)$ [OR]
RewriteCond %{QUERY_STRING}<>6 ^pageNumber=5<>(.+)$ [OR]
RewriteCond %{QUERY_STRING}<>7 ^pageNumber=6<>(.+)$ [OR]
RewriteCond %{QUERY_STRING}<>8 ^pageNumber=7<>(.+)$ [OR]
RewriteCond %{QUERY_STRING}<>9 ^pageNumber=8<>(.+)$ [OR]
RewriteCond %{QUERY_STRING}<>10 ^pageNumber=9<>(.+)$ [OR]
RewriteCond %{QUERY_STRING}<>11 ^pageNumber=10<>(.+)$ [OR]
RewriteCond %{QUERY_STRING}<>12 ^pageNumber=11<>(.+)$ [OR]
RewriteCond %{QUERY_STRING}<>13 ^pageNumber=12<>(.+)$ [OR]
RewriteCond %{QUERY_STRING}<>14 ^pageNumber=13<>(.+)$ [OR]
RewriteCond %{QUERY_STRING}<>15 ^pageNumber=14<>(.+)$ [OR]
RewriteCond %{QUERY_STRING}<>16 ^pageNumber=15<>(.+)$
RewriteRule ^page\.php$ http://www.example.com/page%1.php? [R=301,L]

Note that the "<>" character sequence, although intended to visually-imply concatenation, is meaningless to mod_rewrite and to the regular-expressions parser. It serves only to delimit the two variables so that the regex parser can find the boundary between the value of "{QUERY_STRING}" and the fixed "pageNumber+1" value to be passed into the %1 back-reference.

Basically, if the query string matches the first pattern-part given on the right, then the fixed value corresponding to the pageNumber+1 is taken from the left side and put into %1.

I saw no need to use %{THE_REQUEST}, so I used %{QUERY_STRING} to make the patterns simpler and the processing faster. The first RewriteCond is meant to immediately abort the rule-processing if the query string is not present or if it doesn't match the general 'template' handled by the following 13 RewriteConds; I believe that this may speed things up for you, but it is optional.

Jim

jepler

4:04 pm on Mar 22, 2008 (gmt 0)

10+ Year Member



hmmm... i've attempted to get this to work on two different occasions but was unsuccessful both times. I dropped the optional first RewriteCond.

I'm running Apache/1.3.33(Darwin) with mod_perl/1.26 if that makes a difference.

jdMorgan

5:41 pm on Mar 22, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Be aware that the RewriteConds will match only if the query is exactly "pageNumber=<numbers>" -- No more, no less, and case-sensitive If you have other parameters in the query string, you'll need to adapt the code.

Also, remember that mod_rewrite works only with text strings; It has no knowledge that the parameters are numerical values. Therefore, "03" and "3" are NOT equivalent.

Also, as-shown, the code is for use in .htaccess. For use in server config files, add a leading slash to the RewriteRule pattern.

As stated, this is an example, and in the spirit of this forum it's up to you to modify it to suit and test. But it also happens to be working fine on several sites.

[added] And if you have no other working RewriteRules, you will need to set-up and enable mod_rewrite before using it: Place either both the following lines or only the second one before your rule(s). Only testing can determine whether you need the first line, or are allowed to use it, but it must be present either in your server configuration file or in .htaccess before mod_rewrite will execute:


Options +FollowSymLinks
RewriteEngine on
[/added]

Jim

[edited by: jdMorgan at 5:45 pm (utc) on Mar. 22, 2008]

jepler

3:59 pm on Mar 23, 2008 (gmt 0)

10+ Year Member



Be aware that the RewriteConds will match only if the query is exactly "pageNumber=<numbers>" -- No more, no less, and case-sensitive If you have other parameters in the query string, you'll need to adapt the code.

This is most likely my problem. There is another parameter in the query string so I dropped the $ at the end of each conditional statement, understanding that the $ signifies the ending of the matched string which is not accurate in my case. Is there something more I need to do? All the other things you mentioned have been accounted for.

jdMorgan

4:08 pm on Mar 23, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Reverse the arguments, so that trailing query parameters won't affect the match:

RewriteCond 4<>%{QUERY_STRING} ^([0-9]+)<>pageNumber=3&? [OR]
RewriteCond 5<>%{QUERY_STRING} ^([0-9]+)<>pageNumber=4&? [OR]
... etc.

Unfortunately, to get efficient code, every mod_rewrite routine must be purpose-built to suit the exact requirements and existing conditions. So, since there were unmentioned additional query parameters, the code needs to be modified.

Jim