.htaccess rewrite: subdomain as GET var and path as GET var
Use the first rule to add the subdomain
parameter, without changing the URI, then use the 2nd rule to route the URI to index.php
:
RewriteEngine On
# Parse the subdomain as a variable we can access in PHP, and
# run the main index.php script
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{HTTP_HOST} !^www
RewriteCond %{HTTP_HOST} ^([^\.]+)\.([^\.]+)\.([^\.]+)$
RewriteRule ^(.*)$ /$1?subdomain=%1
# Map all requests to the 'path' get variable in index.php
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?path=$1 [L,QSA]
The second rule needs to have the QSA
flag, otherwise the first rule's query string gets lost. Wildcard .htaccess rewrite subdomain to a subdirectory with subdomain as GET variable
Try this (if you already have some other rewrite rules, put these on top):
RewriteCond %{HTTP_HOST} ^((?!www\.)[^.]+)\.example\.com$
RewriteRule ^ http://example.com/subdomains%{REQUEST_URI}?user=%1 [QSA,L,P]
.htaccess rewrite: subdomain as GET parameter and filepath afterdomain intact
You can use this code in your root .htaccess:
DirectoryIndex index.php
RewriteEngine On
# Parse the subdomain as a variable we can access in PHP, and
# run the main index.php script
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{HTTP_HOST} !^(?:www|mpmain) [NC]
RewriteCond %{HTTP_HOST} ^([^.]+)\.[^.]+\.[^.]+$
RewriteRule ^(.*)$ $1?subdomain=%1 [L,QSA]
.htaccess rewrite a subdomain with a variable
Sure that is possible. But you need to tell a few things apart:
The actual host name in the URL ("subdomain") is not part of the path a RewriteRule
s pattern is internally matched against. You need to use a RewriteCond
to access that information:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^(?:www\.)?whatever\.example\.com$
RewriteRule ^ /file.php?var=1 [L,QSA]
RewriteCond %{HTTP_HOST} ^(?:www\.)?whatever1\.example\.com$
RewriteRule ^ /file.php?var=2 [L,QSA]
A typical variant would be to hand over an actual name instead of a numeric value. Here the GET variable would become v=whatever
or v=whatever1
:RewriteEngine on
RewriteCond %{HTTP_HOST} !^www\.example\.com$
RewriteCond %{HTTP_HOST} ^(?:www\.)?([^.]+)\.example\.com$
RewriteRule ^ /file.php?var=%1 [L,QSA]
This assumes that all hosts/subdomains are served from by same http server, of course, since it is an internal rewrite.In general I would recommend that you take a look at the documentation of the tools you want to use. That documentation is, as typical for OpenSource software, of excellent quality and comes with great examples: https://httpd.apache.org/docs/current/mod/mod_rewrite.html
.htaccess - Subdomain and path as GET var
Replace your 2 rules by these 2 rules:
# Map all requests to the 'path' get variable in dispatcher.php
RewriteCond %{HTTP_HOST} !^www [NC]
RewriteCond %{HTTP_HOST} ^([^.]+)\.[^.]+\.[^.]+$
RewriteRule ^/?$ /dispatcher.php?subdomain=%1 [L,QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{HTTP_HOST} !^www [NC]
RewriteCond %{HTTP_HOST} ^([^.]+)\.[^.]+\.[^.]+$
RewriteRule ^(.+)$ /dispatcher.php?subdomain=%1&path=$1 [L,QSA]
Mod Rewrite Subdomain to PHP with GET variable
You must capture the first part of the domain in a RewriteCond
and then use this in a RewriteRule
. The additional RewriteCond
s are there to prevent www.mydomain.com
and index.php
being rewritten
RewriteEngine on
RewriteCond %{HTTP_HOST} !^www\.
RewriteCond %{REQUEST_URI} !index\.php
RewriteCond %{HTTP_HOST} ^(.+?)\.mydomain\.com$
RewriteRule .* /index.php?username=%1 [L]
But this is only a small part of the needed functionality. Additionally, you must setup DNS entries for all of your username.mydomain.com
domain names or setup a wildcard DNS entry *.mydomain.com
pointing to your host.Otherwise, the client tries to contact jcraine.mydomain.com
, for example, and doesn't find a DNS entry and complains.
If this is a virtual host, you must also add a ServerAlias
for each of your usernames
ServerAlias jcraine.mydomain.com
or a wildcard catching all subdomains ServerAlias *.mydomain.com
Rewrite subdomain and URL-path to URL parameters but allow access to files
If your URLs don't contain dots then exclude dots from your regex - this naturally excludes real files (that contain a dot before the file extension). This avoids the need for a filesystem check.
Your script should handle /index.php?lang=%1
and /index.php?lang=%1&page=
exactly the same, so the first rule is superfluous.
This rule should be first, not embedded in the middle.RewriteRule ^index\.php$ - [L]
Try the following instead:
RewriteRule ^index\.php$ - [L]
RewriteCond %{HTTP_HOST} ^((?!www).+)\.example\.com [NC]
RewriteRule ^([^.]*)$ /index.php?lang=%1&page=$1 [QSA,L]
RewriteRule ^([^.]*)$ /index.php?page=$1 [QSA,L]
Your last rule that rewrites everything else to index.php
, less the lang
URL param is questionable. Why not just include this in the preceding rule and validate the language in your script? Which you need to do anyway.Assuming there is always a subdomain, then your rules could then be reduced to:
RewriteRule ^index\.php$ - [L]
RewriteCond %{HTTP_HOST} ^(.+)\.example\.com [NC]
RewriteRule ^([^.]*)$ /index.php?lang=%1&page=$1 [QSA,L]
Requests for the www
language are then validated by your script and defaulted accordingly, as if the lang
param was not passed at all (which you need to be doing anyway).If your subdomain is entirely optional and you are accessing the domain apex then make it optional (with a non-capturing group) in the regex:
RewriteCond %{HTTP_HOST} ^(?:(.+)\.)?example\.com [NC]
:
The lang
param would then be empty if the domain apex was requested.(Bonus)It would be preferable (more efficient, flexible, etc) to do this in your PHP script, noten.domain.com/hello/there/sir
->index.php?lang=en&page=hello&sub1=there&sub2=sir
.htaccess
.But in .htaccess
you could do something like this (instead of the existing rule):
:
RewriteRule ^([^/.]*)(?:/([^/.]+))?(?:/([^/.]+))?(?:/([^/.]+))?(?:/([^/.]+))?$ /index.php?lang=%1&page=$1&sub1=$2&sub2=$3&sub3=$4&sub4=$5 [QSA,L]
The URL params are empty when that path segment is not present.It is assumed the URL-path does not end in a slash (the above will not match if it does, so a 404 will result). If a trailing slash needs to be permitted then this should be implemented as a canonical redirect to remove the trailing slash. Or reverse the logic to enforce a trailing slash.
This particular example allows up to 4 additional "sub" path segments, eg. hello/1/2/3/4
. You can extend this method to allow up to 8 (since there is a limit of 9 backreferences in the Apache syntax) if required. Any more and you will need to use PHP. (You could potentially handle more using .htaccess
, but it will get very messy as you will need to employ additional conditions to capture subsequent path segments.)
I tried adding RewriteCond %{REQUEST_FILENAME} !-f
to respect local files but that breaks the whole file it seems
That should also be sufficient (if dots are permitted in your URLs). But I wonder where you were putting it? It should not "break" anything - it simply prevents the rule from being processed if the request does map to a file - the rule is "ignored".This is of course assuming you are correctly linking to your resources/static assets using root-relative (starting with a slash) or absolute (starting with scheme + hostname) URLs. If you are using relative URLs then they will probably result in 404s. If this is the case then see my answer to the following question on the Webmasters stack:
- https://webmasters.stackexchange.com/questions/86450/htaccess-rewrite-url-leads-to-missing-css
htaccess rules to rewrite subfolder to a GET variable
This should do it for you:
RewriteEngine on
RewriteCond %{HTTP_HOST} =sub.example.com
# Following condition added to support changed requirement, see comments
RewriteCond %{QUERY_STRING} !(?:^|&)var=
RewriteCond %{REQUEST_URI} !^/admin/
RewriteRule ^(.*)$ http://www.example.com/?var=$1 [R=301,L]
This will drop any query string that was in the original request. If you want to keep any query string, and just append 'var=...' to it, then add QSA
to the flags at the end of the last line, separated by a comma. Rewrite subdomain to subdirectory in Apache .htaccess file
Rather confusing, this should implicitly trigger an external 302 (temporary) redirect, not an internal rewrite - when specifying a different host in the substitution string to the one being requested. (Although in my experience, any absolute URL in the substitution string triggers an external redirect.)RewriteCond %{HTTP_HOST} ^office.example.com$
RewriteRule ^(.*)$ https://example.com/office/$1 [L,NC,QSA]
If it does trigger an internal rewrite (as indicated by the logs) then the requested hostname does not change (since this is not a separate request) and you will indeed get a rewrite loop.
However, if "the subdomain is an alias of the main domain" and a rewrite is what's required, then there is no need to specify a hostname in the substitution string and you will indeed need to make additional checks to prevent an internal rewrite loop (500 error).
Try the following instead:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^office\.example\.com [NC]
RewriteRule !^office office%{REQUEST_URI} [L]
...to exclude any requests (including rewritten requests) that already start /office
.No need for the NC
and QSA
flags.
Alternatively, to only target direct requests (not rewritten requests) you could check the REDIRECT_STATUS
environment variable instead (which is empty on the initial request and set to "200", as in 200 OK, after the first successful rewrite).
For example:
RewriteCond %{HTTP_HOST} ^office\.example\.com [NC]
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule (.*) office/$1 [L]
This has the added "benefit" that you can potentially have a sub-subdirectory called /office
as well. ie. /office/office
.UPDATE: A third version is to check against the REQUEST_URI
server variable. However, I would not expect this to be any different from the first version above.
RewriteCond %{HTTP_HOST} ^office\.example\.com [NC]
RewriteCond %{REQUEST_URI} !^/office
RewriteRule ^ office%{REQUEST_URI} [L]
Sadly enough, both your suggestions gave the same error as before.Two things to try...
Add a slash prefix on the substitution string. ie.
/office%{REQUEST_URI}
and/office/$1
respectively. This changes the substitution string into a URL-path, rather than a relative filesystem path. However, I wouldn't necessarily expect this to make any difference in this respect. (It would be required for an external redirect.)Use the
END
flag instead ofL
on theRewriteRule
directives - this is an Apache 2.4 addition that should halt all processing. TheL
flag "only" ends the current pass before restarting the rewriting process (hence the need for additional checks to prevent rewrite loops).
But now any other file (IMG, CSS) gives an 404.The above rewrites everything, so it will naturally rewrite all static resources if they don't already start
/office
. (If they already start /office
then they should already be excluded by the above rules.)To exclude common resources, you could make an exception (an additional RewriteCond
directive) to exclude specific file extensions. For example:
RewriteCond %{REQUEST_URI} !\.(css|js|png|jpg|gif)$
And/or add an additional RewriteCond
directive to exclude requests that already map to physical files (although this is "marginally" more expensive). For example:RewriteCond %{REQUEST_FILENAME} !-f
Summary:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^office\.example\.com [NC]
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{REQUEST_URI} !\.(css|js|png|jpg|gif)$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.*) office/$1 [END]
Related Topics
Best Way to Escape and Create a Slug
Replace Any Url's Within a String of Text, to Clickable Links with PHP
Make Woocommerce Checkout Phone Field Optional Based on Shipping Country
Use MySQL_Fetch_Array() with Foreach() Instead of While()
What Is the Correct Format for a Blowfish Salt Using PHP's Crypt
Typecasting VS Function to Convert Variable Type in PHP
Add a Custom Checkbox in Woocommerce Checkout Which Value Shows in Admin Edit Order
How to Make a Chat Room Script with PHP
How to Generate a Round Robin Tournament in PHP and MySQL
Print Directly to Network Printer Using PHP
PHP Displaying Unread Mail Count
How to Remove Email Addresses and Links from a String in PHP