26

I'm setting up Apache rewrite rules to tidy up my CodeIgniter URLs.

This question (and lots of forum posts etc that I've found around the place) document the use of the following rule (or something very similar):

RewriteEngine on
RewriteCond $1 !^(index\.php|phpinfo\.php|images|robots\.txt|sitemap\.xml\.gz|sitemap\.xml|assets)
RewriteRule ^(.*)$ /index.php/$1 [L]

I know the $1 after the RewriteRule refers to the captured string from (.*), but what does the first $1 (straight after the RewriteCond) represent? A lot of examples I've seen use something like %{REQUEST_URI} as the first argument for RewriteCond.

Community
  • 1
  • 1
Highly Irregular
  • 38,000
  • 12
  • 52
  • 70

2 Answers2

35

The $1 is basically the captured contents of everything from the start and the end of the string. In other words, $1 = (.*).

In your rewrite, the ^ signifies the start of the string, the (.*) says to match anything, and the $ signifies the end of the string. So, basically, it's saying grab everything from the start to the end of the string and assign that value to $1.

So if I type in www.example.com/tacos-are-good, then $1 = "tacos-are-good". So your end rewrite will actually be www.example.com/index.php/tacos-are-good.

Here's a cheat sheet for ModRewrite which may be of help: http://www.addedbytes.com/cheat-sheets/mod_rewrite-cheat-sheet/

sbeliv01
  • 11,550
  • 2
  • 23
  • 24
  • 4
    So both instances of $1 refer to the same value then? – Highly Irregular Nov 14 '12 at 00:44
  • 1
    Yes. In the `RewriteCond`, it's basically saying that it'll run the rewrite as long as $1 doesn't equal on of the files listed to the right of the condition. – sbeliv01 Nov 14 '12 at 04:21
  • 1
    Question was for RewriteCond $1 and now for RewriteRule – user2957058 Jun 29 '19 at 16:42
  • 1
    To clarify, `$1` in the `RewriteRule` becomes whatever was captured with the regex `^(.*)$` from the `RewriteRule`. Then the `$1` in `RewriteCond` is a [backreference](http://httpd.apache.org/docs/trunk/rewrite/intro.html#InternalBackRefs) to that same capture group, which is why the `$1` in the `RewriteCond` and the `RewriteRule` are the same value. My confusion came from the fact that the `RewriteCond` has a separate capture group (`(index\.php|...`). But that would become `%1` in the `RewriteRule` if it was used at all. See https://stackoverflow.com/a/32383175/1499877 for additional info. – WOUNDEDStevenJones Jul 29 '21 at 18:09
  • @WOUNDEDStevenJones Thanks for the explanation! What puzzled my comprehension is that in the file line order first come the `RewriteCondition(s)` then the `RewriteRule`. Our conventions is to read from top to bottom and assume that to be the processing chronology. Which mostly is true in .htaccess. The tricky part in understanding is: First comes the "RegEx matching part" on the `RewriteRule` line, then this match is checked against several RewriteCondition(s) in the lines above, and if they all were fulfilled, the `RewriteRule` line continues with the "replacement pattern" on the same line. – porg Feb 02 '23 at 13:35
9

$1 represents the match from the first set of parentheses in the regular expression that follows it. ($2 would match the second set of parentheses - if given)

For example, the regular expression matches anything that is NOT "index.php" or "phpinfo.php", etc. So, the rewrite condition is passed if the requested url is not one of those, and the matched section is then passed to the rewriterule.

swatkins
  • 13,530
  • 4
  • 46
  • 78
  • 4
    `$1` represents the match from the first set of parentheses in the RewriteRule regex, not in the RewriteCond regex. – xhienne Jul 02 '18 at 15:40