What does the =$1 mean in url rewriting?

江枫思渺然 提交于 2020-06-26 14:49:09

问题


I can't find any information on stackoverflow or google about the meaning of =$1. I get superficial information but nothing for beginners like me. What does it do?

If I have something like this:

www.website.com/profile.php?simon

Does the name simon correspond to the $1 variable and why 1?

This is how I understand it:

  • (.*) profile/profile.php?id=$1

The bold corresponds to:

  • www.website.com/profile.php?id=simon

Converted with rewrite it becomes:

  • www.website.com/profile/simon

Am I missing something here?

Edit:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteCond %{REQUEST_FILENAME}.php -d
RewriteRule ^(.*)$ /profile/index.php?id=$1

Does this change

localhost/test/index.php?philip to: localhost/test/profile/philip

I tried to enter the url but it failed. I understand what regex does but somehow im utterly confusing how the replacement works.


回答1:


Let me try to explain in layman's terms.

Let's say you would normally link to a page like this...

/listing.php?id=2146_east_fifth_street

Then you create a rewrite rule like this...

RewriteRule ^([A-Za-z0-9_-]+)$ listing.php?id=$1 [NC,L]

This part ^([A-Za-z0-9_-]+)$ says to accept any querystring parameter with uppercase letters / lowercase letters / 0-9 / underscores / hyphens

This part listing.php?id=$1 says what page will be served up to the browser. the $1 asks for the first querystring parameter and appends it to the URL like this... your-domain.com/2146_east_fifth_street

That's what you see in the URL bar instead of... your-domain.com/listing.php?id=2146_east_fifth_street

EDIT

The second part of the rewrite rule is where the "real" page is located.

If you want your url to read /profile/philip

Your rewrite rule would start with /profile/ like this...

RewriteRule ^profile/(.*)$ path/to/the/real/file/index.php?id=$1




回答2:


Backreference:

RewriteRule ^.*$ /?id=$1

$1 would be blank

RewriteRule ^(.*)$ /?id=$1

$1 would be whatever .* matched

RewriteRule ^(a|b|c)/(d|e|f)$ /?id=$1-$2

$1 would be either "a", "b", or "c", depending on which one matched, and $2 would be either "d", "e", or "f", depending on which one matched.

See: http://httpd.apache.org/docs/trunk/rewrite/intro.html#regex

One important thing here has to be remembered: Whenever you use parentheses in Pattern or in one of the CondPattern, back-references are internally created which can be used with the strings $N and %N (see below). These are available for creating the Substitution parameter of a RewriteRule or the TestString parameter of a RewriteCond.

Captures in the RewriteRule patterns are (counterintuitively) available to all preceding RewriteCond directives, because the RewriteRule expression is evaluated before the individual conditions.

Figure 1 shows to which locations the back-references are transferred for expansion as well as illustrating the flow of the RewriteRule, RewriteCond matching. In the next chapters, we will be exploring how to use these back-references, so do not fret if it seems a bit alien to you at first.


Does this change

localhost/test/index.php?philip to: localhost/test/profile/philip

No, It changes localhost/test/profile/philip to localhost/profile/index.php?id=philip. Assuming that the rule is in an htaccess file that is in your "profile" directory, then:

  1. Browser types in or clicks on the link: localhost/test/profile/philip
  2. The request is sent to localhost: /test/profile/philip
  3. The request makes its way through apache's processing pipeline and mod_rewrite is applied to it, and the request is truncated to philip
  4. Assuming that philip is neither a directory or file, the rule matches (.*) to it, and the string philip is captured
  5. The rule then rewrites the request to /profile/index.php?id=philip



回答3:


First, use Apache documentation rather than Google searches or Forums it's more helpful.

http://httpd.apache.org/docs/2.2/rewrite/intro.html#regex

And this

http://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewritecond

Now (.*) is a parenthesized capture group in Regex. It says to match any single character and the asterisk means to repeat it 0 or more times.

When there is only 1 capture group. The numbered back reference is $1. Additional capture groups used or added will then be $2, $3 and so on.

For this example

www.website.com/profile/simon

You would get this rewrite rule.

RewriteRule (.*) profile/profile.php?id=$1

But your back reference $1 won't be simon, it will be profile/simon because you matched all characters requested using (.*).

If you only want to match simon you need to use a partial match like this.

RewriteCond %{REQUEST_FILENAME}.php -f
RewriteCond %{REQUEST_FILENAME}.php -d
RewriteRule ^profile/(.+)/?$ profile/profile.php?id=$1

Then your $1 will only be simon and also the rule won't match any empty strings, meaning if there is no text after /profile/ it won't process the rewrite.




回答4:


in .htaccess $1 is a back-reference to a group, usually from a regex statement. Each group has its own reference, so a rewrite like

RewriteRule /profile/(.*)/([0-9]) /profile/index.php/$1/$2

$1 would equal the value of (.*) that group

$2 would equal the value of ([0-9]) which can only include numbers

and so on...

It helps when id numbers and url's are dynamic. So you do not need to manually add them one by one.

Example url:

 website.com/profile/idealcastle/25555

And then in php or other languages, you can pull these "url segments". Just like using a "query" parameter, ?id=simon It's much better to use proper urls for SEO purposes.



来源:https://stackoverflow.com/questions/32382466/what-does-the-1-mean-in-url-rewriting

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!