Could anyone explain the following line please?
RewriteRule ^(.*)$ /index.php/$1 [L]
The parts of the rewrite rule break down as follows:
RewriteRule
Indicates this line will be a rewrite rule, as opposed to a rewrite condition or one of the other rewrite engine directives
^(.*)$
Matches all characters (.*) from the beggining ^ to the end $ of the request
/index.php/$1
The request will be re-written with the data matched by (.*) in the previous example being substituted for $1.
[L]
This tells mod_rewrite that if the pattern in step 2 matches, apply this rule as the "Last" rule, and don't apply anymore.
The mod_rewrite documentation is really comprehensive, but admittedly a lot to wade through to decode such a simple example.
The net effect is that all requests will be routed through index.php, a pattern seen in many model-view-controller implementations for PHP. index.php can examine the requested URL segments (and potentially whether the request was made via GET or POST) and use this information to dynamically invoke a certain script, without the location of that script having to match the directory structure implied by the request URI.
For example, /users/john/files/index might invoke the function index('john') in a file called user_files.php stored in a scripts directory. Without mod_rewrite, the more traditional URL would probably use an arguably less readable query string and invoke the file directly: /user_files.php?action=index&user=john.
That will cause every request to be handled by index.php, which can extract the actual request from $_SERVER['REQUEST_URI']
So, a request for /foo/bar will be rewritten as /index.php/foo/bar
(I'm commenting here because I don't yet have the rep's to comment the answers)
Point #2 in meagar's answer doesn't seem exactly right to me. I might be out on a limb here (I've been searching all over for help with my .htaccess rewrites...), and I'd be glad for any clarification, but this is from the Apache 2.2 documentation on RewriteRule:
What is matched?
The Pattern will initially be matched against the part of the URL after the hostname and port, and before the query string. If you wish to match against the hostname, port, or query string, use a RewriteCond with the %{HTTP_HOST}, %{SERVER_PORT}, or %{QUERY_STRING} variables respectively.
To me that seems to say that for a URL of
http: // some.host.com/~user/folder/index.php?param=value
the part that will actually be matched is
~user/folder/index.php
So that is not matching "all characters (.*) from the beggining ^ to the end $ of the request", unless "the request" doesn't mean what I thought it does.
Related
I imagine this has to be a common scenario but I'm struggling to describe it sufficiently well or to find a working answer!
Essentially I want to make hundreds of URLS that include unique reference codes but that are easy to type in the form example.com/aabbcc, which will be intercepted and all delivered to a PHP script for validating that code, located somewhere like example.com/script.php.
I need the subdirectory part of the URL (aabbcc, in this example) to become a GET parameter for that script, so a URL like the one above would be sent to example.com/script.php?id=aabbcc, while hiding this more complicated URL from the user.
I can see from other .htaccess examples that this must be possible, but I can't find one doing this.
Is there a .htaccess solution for it? Is there something else even more basic? Your help is appreciated in steering me.
If your "unique reference codes" consist of 6 lowercase letters, as in your example then you can do something like the following in your root .htaccess file using mod_rewrite:
RewriteEngine
# Internally rewrite "/abcdef" to "script.php?id=abcdef"
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^[a-z]{6}$ script.php?id=$0 [L]
If you don't need direct access to any subdirectories off the root that also happen to match a "unique reference code" then you can remove the preceding condition (RewriteCond directive). With the condition in place then you naturally can't access any "unique access codes" that happen to also match the name of a subdirectory.
$0 is a backreference to the entire URL-path that the RewriteRule pattern (first argument) matches against.
Reference
Apache mod-rewrite Documentation - Contents
Apache mod_rewrite Introduction
Apache mod_rewrite Reference
RewriteRule Directive
RewriteCond Directive
I am trying to do the following:
User visits URL with query parameter: http://www.example.com/?invite=1234
I then want them to be deep linked into the app on their iOS device, so they go to: app_name://1234
Any suggestions on how to accomplish this in my .htaccess file?
I tried this but it doesn't work:
RewriteEngine On # Turn on the rewriting engine
RewriteRule ^invite/(.*)/$ app_name://$1 [NC,L]
If RewriteRule won't work, can anyone send me an example code for RewriteCond or JavaScript to achieve what I need?
Not sure how this will work with the iOS device, but anyway...
RewriteRule ^invite/(.*)/$ app_name://$1 [NC,L]
This doesn't match the given URL. This would match a requested URL of the form example.com/invite/1234/. However, you are also matching anything - your example URL contains digits only.
The RewriteRule pattern matches against the URL-path only, you need to use a RewriteCond directive in order to match the query string. So, to match example.com/?invite=1234 (which has an empty URL-path), you would need to do something like the following instead:
RewriteCond %{QUERY_STRING} ^invite=([^&]+)
RewriteRule ^$ app_name://%1 [R,L]
The %1 backreference refers back to the last matched CondPattern.
I've also restricted the invite parameter value to at least 1 character - or do you really want to allow empty parameter values through? If the value can be only digits then you should limit the pattern to only digits. eg. ^invite=(\d+).
I've include the R flag - since this would have to be an external redirect - if it's going to work at all.
However, this may not work at all unless Apache is aware of the app_name protocol. If its not then it will simply be seen as a relative URL and result in a malformed redirect.
I have multiple TLD's (domainX.com, domainY.net, ...) pointing towards the same folder. In this folder I would like to add a .htaccess file to redirect ALL www and non-www URL's that aren't domainY.com to domainY.com.
There is one twist here however. I have some subdomains: alfa.domainY.com and beta.domainY.com and gamma.domainY.com set-up, which in all my tests keep redirecting to domainY.com.
Any chance anyone can give me a successful bit of code here?
EDIT: Maybe also add some #Comments, I noticed most answers here lack that, and I think it means some of them can't be reused as people don't know what they do. I can also add this myself afterwards.
Try adding these rules to the htaccess file of your document root:
RewriteEngine On
RewriteCond %{HTTP_HOST} !domainY\.net$ [NC]
RewriteRule ^(.*)$ http://domainY.net/$1 [L,R=301]
The expression matching the host will fail for any alpha.domainY.net because it only matches against the TLD (.net) and domain (domainY).
The first line turns on the rewrite engine.
The second line, the condition, is a true/false expression that is applied to the immediately following rule. In this case, it checks the request's Host: header, and if it ends with domainY.net, then the condition fails, because of the ! in front.
The third line is the rule, the URI is used to match against the pattern ^(.*)$ which essentially matches everything, and is captured via the parentheses. Then the next bit is the target. If the rule matches, which it does because the pattern matches everything, then the target is applied, and in this case, it redirects the browser to domainY.net and passes the same URI along with it via the regex backreference $1.
I am setting up a MVC style routing system using mod rewrite within an .htaccess file (and some php parsing too.)
I need to be able to direct different URLs to different php files that will be used as controllers. (index.php, admin.php, etc...)
I have found and edited a rewrite rule that does this well by looking at the first word after the first slash:
RewriteCond %{REQUEST_URI} ^/stats(.*)
RewriteRule ^(.*)$ /hello.php/$1 [L]
However, my problem is I want it to rewrite based on the 2nd word, not the first. I want the first word to be a username. So I want this:
http://www.samplesite.com/username/admin to redirect to admin.php
instead of:
http://www.samplesite.com/admin
I think I just need to edit the rewrite rule slightly with a 'anything can be here' type variable, but I'm unsure how to do that.
I guess you can prefix [^/]+/ to match and ignore that username/
RewriteCond %{REQUEST_URI} ^/[^/]+/stats(.*)
RewriteRule ^[^/]+/(.*)$ /hello.php/$1 [L]
then http://www.samplesite.com/username/statsadmin will be redirecte to http://www.samplesite.com/hello.php/statsadmin (or so, I do not know the .htaccess file)
To answer your question, "an anything can be here type variable" would be something like a full-stop . - it means "any character". Also the asterisk * means "zero or more of the preceding character or parenthesized grouped characters".
But I don't think you need that...If your matching url will always end in "admin" then you can use the dollar sign $ to match the end of the string.
RewriteRule admin$ admin.php [R,NC,L]
Rewrites www.anything.at/all/that/ends/in/admin to www.anything.at/admin.php
I need a bit of ISAPI syntax help, I am about to put live a new site and want to archive the old forum onto an archive sub domain.
The forum is in ASP and currently has this URL
http://www.mywebsite.co.uk/forum/forum_posts.asp?TID=34419
http://www.mywebsite.co.uk/forum/forum_topics.asp?FID=47
I want every request for the forum to be 301 redirected to:
http://archive.mywebsite.co.uk/forum/forum_posts.asp?TID=34419
http://archive.mywebsite.co.uk/forum/forum_topics.asp?FID=47
Basically anything with in the forum folder with .asp extension with or without a query string - Any help greatly appreciated.
Thanks
For redirecting a url to a subdomain, it has been a few months since your question, but maybe this will still help.
Assuming you're using isapi_rewrite v3, try this:
RewriteCond %{HTTP:Host} ^www\.
RewriteRule ^/forum/(.*\.asp)$ http://archive.mywebsite.co.uk/forum/$1 [NC,R=301]
The first line looks for host beginning with www. (with the trailing dot). This makes sure you don't get an infinite loop, redirecting archive to itself. The trailing dot is being picky at doing only www, and not others like www2.
The second line looks for /forum/, then captures (...) any characters .* and literal dot and asp \.asp, ending the url $
It then goes to your subdomain in the /forum/ folder (since /forum/ wasn't captured, we need to repeat it), and the entire rest of the url that was captured $1.
The NC means not case-sensitive, so all this can be mixed upper and lower case.
The R=301 means redirect, and make it a permanent 301 redirect since this isn't temporary.
In the v3 rules, querystring parameters are handled entirely separately from the rules, so you don't have to do anything at all here. If there are no parameters, then this works. If there are parameters, they are passed on as in your question above.
This ignores http vs https. It will redirect to http, so if the original was https, there will probably be a browser warning. There are ways to handle it, but I didn't want to clutter the basic answer.
Having the domain itself in the rewrite rule is always a little weird looking to me, since you might want to move it around. You can capture the rest of the host in the first line, and use it in the second.
RewriteCond %{HTTP:Host} ^www\.(.*)$
RewriteRule ^/forum/(.*\.asp)$ http://archive.%1/forum/$1 [NC,R=301]
This is similar to above, with the addition that the host after the www-dot is captured, to the end of the line (.*)$ I'm not sure the $ is required here, but it makes it explicit we want it all.
RewriteCond captures are numbered with a percent sign, so %1 in the rewrite rule substitutes the host after the subdomain, and $1 still means substituting the captured ...asp url.