Forum Moderators: phranque
My aim: to run every gif file through a php script which modifies it (adds a copyright notice to the comment field) before sending it out. So, when a request is made for <http://www.mysite.com/graphics/abc/image.gif>, I need it to redirect to <http://www.mysite.com/secure.php?url=graphics~abc~image.gif>.
Here's my start, for what it's worth (not much), which for some reason or other just doesn't do anything:
RewriteEngine on
RewriteCond %{REQUEST_URI} (.*)\.gif
RewriteRule ^/(.*)\.gif /secure.php?url=$0 [L,NE] Aside from it not working, of course, I have also yet to take into consideration replacing slashes with tildes, or making sure the file requested doesn't have ".php" in it, to prevent looping.
Any help would be appreciated.
Welcome to WebmasterWorld [webmasterworld.com]!
This recent thread [webmasterworld.com] illustrates a method to accomplish what you want to do.
Jim
Some reading of the Apache manual did me well... for the record, here's what I ended up getting to work:
RewriteEngine on
RewriteCond %{REQUEST_URI} ^(.*).gif$
ReWriteRule ^(.*)?/(.*)?$ $1~$2
ReWriteRule ^(.*).gif$ secure.php?url=$1.gif
Glad that link at least got you started... Since almost all cases posted here are different, citing a related example is usually the best we can do without writing your code for you - a practice which is discouraged here because it often leads to dependence instead of learning.
Here's a compact, speedier version of your code:
RewriteEngine on
ReWriteRule ^([^/]*)/([^.]*\.gif)$ $1~$2
ReWriteRule \.gif$ secure.php?url=$1.gif [L]
Jim
On line 2, [^/]* and [^.]* specify that the characters "/" and "." respectively cannot be present, right? Why are those in there?
What's the difference in how line 3 operates between your version and mine? Why did you rewrite it? Why is there no start anchor ("^")?
What's the purpose of the [L] flag? There are no more rules after this (this is the only thing in the .htaccess file). Won't Apache just stop when it reaches the end of the file? Why do I need to tell it to stop?
You escaped periods. I didn't. Mine worked anyway. Why escape periods? Just in case it happens to confuse Apache in some other situation?
Because it is much faster. The subpattern ([^/]*) says, "grab as many characters as possible up to the first slash and put that in $1. It is less ambiguous than having (.*) in there. If you use (.*), mod_rewrite grabs the whole string and puts it into $1, and then has to "back up" into it to find the match for the slash and for the rest of the pattern. If you put enough (.*) elements in a pattern, you can get very unpredictable results because mod_rewrite has trouble trying to find the "boundaries" between the fixed and variable parts of your pattern.
The default will be to match as much of the input string as possible to the first (.*) and work from there. If the rest of the pattern can't be satisfied, mod_rewrite will "back up" into the first match, and see if it can find a match by taking some of the previously-matched text out of the first subpattern match. It does this backing-up one character at a time, so the number of required matching attempts then becomes proportional to the length of the input string. It is simply faster to work forward until a positive stop is reached, put that into the first back-reference and carry on from there. I hope that makes sense. The main point is to use the most unambiguous pattern possible. This applies to regular expressions used in other languages, too -- Not just mod_rewrite.
> What's the difference in how line 3 operates between your version and mine? Why did you rewrite it? Why is there no start anchor ("^")?
Hah! The difference is that mine has a bug! I dropped your back-reference! Teach me to code when I'm tired...
How about:
RewriteRule ^([^.]*)\.gif$ secure.php?url=$1.gif [L]
instead? > What's the purpose of the [L] flag? There are no more rules after this (this is the only thing in the .htaccess file). Won't Apache just stop when it reaches the end of the file? Why do I need to tell it to stop?
Habit, pure habit. And a good habit. Your .htaccess contains only one rule today. Tomorrow, who knows? Always use [L] unless you have a known good reason not to. :)
> You escaped periods. I didn't. Mine worked anyway. Why escape periods? Just in case it happens to confuse Apache in some other situation?
In regular expressions an unescaped period means "match any single character." That could lead to a very hard-to-find ambiguity in your pattern. You need to escape the following characters in regex patterns in mod_rewrite:
$^*.+?(){}[]¦\ <space> and "-" under certain circumstances when used within character classes inside []
...and I may have forgotten a few.
Jim