How to create dynamic subdomain using PHP and htaccess? - php

I have one problem:
I want to set up PHP and htaccess to make dynamic subdomains. And I can not figure out how.
Currently my URL looks like this:
www.exemple.com/index.php?subdomain=mike&component=content&id=26&title=people-love-apps
I need it to look like this:
www.mike.exemple.com/content/26/people-love-apps.html
I know it can be done but I do not know a solution how to do it.
Is very important to me with $ _GET [] functions to read parameter in the URL.
The problem is that users on my site make their web site and get a free domain (sub-domain) automatically. This should be automatic.
Thanks!

You can't make dynamic subdomains with .htaccess
You will need to configure the apache virtual host to accept requests for multiple domains
See the Apache documentation - Using Name Based Virtual Hosts
<VirtualHost *:80>
ServerName www.example.com
ServerAlias example.com *.example.com
DocumentRoot /www/domain
</VirtualHost>
Adding the wildcard subdomain *.example.com, your PHP application will receive all requests for any domain below example.com, ie garbage.example.com, busted.example.com, llama.example.com, etc.
Creating Wildcard Sub Domain Using Apache VirtualHost
Multiple Domains to One Virtual Host | Wildcard Host (shared hosting)?
Apache default virtual host for multiple domains
At this point, your application will have to determine the validity of the subdomain and display the appropriate error for unknown subs.
From there, parse the domain for mike.

OF COURSE you can interprete dynamic subdomains with htaccess.
The following rule will solve the problem.
RewriteCond %{HTTP_HOST} www\.([^.]+)\.example\.com [NC]
RewriteRule ^/content/([0-9]+)/([a-zA-Z0-9_\-])\.html /index.php?subdomain=%1&component=content&id=$1&title=$2 [L]
so anyone visting
www.mike.exemple.com/content/26/people-love-apps.html
will see the content of
www.exemple.com/index.php?subdomain=mike&component=content&id=26&title=people-love-apps

Related

Multiple apps, multiple versions of the app under the same domain. How to configure apache server, routes and relative paths to make it work?

My team's server is set up in such as way: We have one domain name, which seems like already a subdomain of the company's domain. We want to host multiple applications under this one domain. We'd even like to have a production version and staging version for each of the apps on the server.
Document root is an empty folder. Applications sit outside of the document root.
we are trying to use the first token in the URL path to find out which app we try to access, then somehow redirect to it (internally or externally).
Here is a structure equivalent to how the directories are organized.
/usr/local/var/www <- Document Root
/usr/local/var/app1 <- application 1
------------------/public/index.php
------------------/public/css
/usr/local/var/app2 <- application 2
/usr/local/var/app1.stg <- application 1 staging version, code is exactly the same as application1
/usr/local/var/app2.stg <- application 2 staging version, code is exactly the same as application2
Here are the relevant settings in httpd.conf
DocumentRoot /usr/local/var/www
<Directory "/usr/local/var/www">
AllowOverride None
Require all granted
</Directory>
Alias "/app1" "/usr/local/var/app1"
Alias "/app2" "/usr/local/var/app2"
<VirtualHost *:80>
# rewriting rules to make the routing work
# There is only one vhost so it can actually be removed
</VirtualHost>
When we access https://sub.domain.com/app1, we expect to go to app1
When we access https://sub.domain.com/app1.stg, we expect to go to app1.stg
The applications are written in PHP. This server configuration means we have to include the "path to the application" in the routes and rewrite rules, and use the "full absolute path" in all the resource references.
For example, a route will look like
$router->map("GET", "/app1/action", SomeController);
A css reference will be: (even though relative path is given, it behaves just like a relative path to the DocRoot (with "/" in front). You can see it in this detailed post)
<link href="app1/public/css/style.css" type="text/css" rel="stylesheet"/>
These will be sufficient to make both apps work, but the staging version is not going to work, because it contains EXACTLY THE SAME copy of code (which is how it's intended to be, to test out in staging environment, then push to production environment).
If I want both versions to work, I have to code the paths dynamically, namely using CONTEXT_DOCUMENT_ROOT or some other server variable to figure out which app version it's in, and have two copies of routes, one starting with app1, the other app1.stg. I also have to have separate rewriting rule for each version.
QUESTION
With the server setup restriction applied (one domain name, distinguish apps with the way I described, etc..), is it possible to use only relative paths, write routes with respective to only the app itself? Some like:
<link href="css/style.css" type="text/css" rel="stylesheet"/>
$router->map("GET", "/action", SomeController);
In other words, I have to change the server setup within the constraints, so that the app can be written in a way without caring how the server is set up.
I know one way is to use different ports for each app/version, but apparently the server admin doesn't like the idea.
I've broken down the problem into steps in this question. It's quite long but if you are willing to follow through, it should provide much more details.
If the question is not clear enough, the per-user directory looks quite like what I want to achieve. But instead of user directory, I want the app directory in place of it. Of course I never used per-user directory so I dont know if it actually behaves the way I think it does.
So I understand that we can have multiple hostnames in /etc/hosts mapped to one IP address. Can I just use that hostname as the ServerName in apache config, and access in the browser by typing that hostname? The website is for internal usage so should only be accessed within company's network.
In /etc/hosts:
123.45.67.89 app1.team-server-name app2.team-server-name
In httpd.conf:
<VirtualHost>
ServerName app1.team-server-name
DocumentRoot /usr/local/var/app1/public
</VirtualHost>
<VirtualHost>
ServerName app2.team-server-name
DocumentRoot /usr/local/var/app2/public
</VirtualHost>
This is quite the lengthy question, thank you for providing so much detail.
I would opt for a different approach than you are currently attempting. Instead of trying to serve each of these applications out of a folder, set up each of them as a domain based vhost. Use something like app1.local or whatever for the hostname and be sure to add the entries to your /etc/hosts file under 127.0.0.1. Make sure the listen directive for these vhosts is on the loopback (127.0.0.1:80). Each of these apps should function as if they were installed at the document root of their own server. All the CSS should assume its at 'css/style.css' relative to /.
Now that you have all of the apps setup on the loopback, you can setup a reverse proxy from the vhost listening on the public interface to proxy all of the application locations to their appropriate loopback vhost after you remove the /app1 prefix from the request.
I haven't used Apache 2.x for a very long time, but the concepts are the same as nginx.
location /foo {
rewrite /foo/(.*) /$1 break;
proxy_pass http://app1.local;
proxy_redirect off;
proxy_set_header Host $host;
}
The biggest issue with this approach is that the applications that are being proxied either need to use relative paths everywhere, or they need to have some kind of configurable prefix that is prepended to the urls. Most frameworks will support the prefix option. For Example: https://laravel.com/docs/5.6/urls This prefix can be used for asset (css/js/jpg) loading as well, but only from files that execute PHP.
I end up finding a solution with one compromise.
DocumentRoot "/usr/local/var/www"
Alias /app1 /usr/local/var/app1/public
<Directory "/usr/local/var/www">
RewriteEngine On
RewriteRule ^/?$ /app1/ [R,L]
RewriteRule (.*) /app1/$1 [R,L]
</Directory>
<VirtualHost *:80>
<Directory "/usr/local/var/app1">
Require all granted
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# calls index.php (REQUEST_URI is still the same as before)
RewriteRule ^ index.php [L]
</Directory>
</VirtualHost>
All relative paths can be rewritten normally.
Routes and requests will need to start with app name.
$router->map("GET", "/app1/hello2", SomeController);
// navigation bar. URI for another tab:
<li>Hello 2</li>
If we want to have multiple versions of the app, the main thing to do is to know which version we are in so the app can send the correct request uri. This can be done by checking the REQUEST_URI and remember which version is being called when index.php is called up. Then in the request (e.g. navigation src), append it in front of the action.
There are different ways to do this, such as writing your html templates in php, so you can access php variables. I used twig so I can pass the value to the twig templates from php. But I still don't like to have all these stuff in my static code, so I decided to just get rid of the staging version.
If the project is serious enough to require a staging version, then a better suitable environment should be provided.

Creating unlimited subdomains that redirect to different IP's in PHP

So iv'e been trying to find the right path for me for my situation but couldn't just find the right answer.
So what i need to do is a php script that will create a subdomain that redirects to an IP that will be sent from my post request.
Example -
I post to script.php - ?username='test'&ip='127.0.0.1'
I need this post request to create a subdomain with this username(the username will be used for the subdomain - test.mysite.com
visiting test.mysite.com will redirect to 127.0.0.1
What im trying to achive is something like a dns service.
Is it possible? Do i need to ask my host for something(Godaddy/IIS Server)
Thanks ! Really appreciate any lead.
This requires 3 steps:
You need to create a wildcard DNS entry for subdomains of your domain
*.example.com A 192.0.0.10
You then need to setup a new vhost entry for your apache server. This should come after the vhost entry for your existing server, if it's running on the same machine as this subdomain redirection system.
NameVirtualHost *:80
<VirtualHost *:80>
DocumentRoot /var/www
ServerName www.example.com
ServerAlias *.example.com
</VirtualHost>
Finally, you write your index.php script to get $_SERVER['HTTP_HOST'] and based on that, to do a lookup in the database for your subdomain name, and send the header('Location:') based on a successful lookup in the database.

How to manage multiple cities in classified site?

I am working on classified site. I am using PHP and MySql for that.
On my site when user select their city that time i want to change website url like in subdomain style. foreg:-
http://cityname.mywebsitename.com
Only one thing in my mind to implement this is creating sub domains for all cities. But it would be more difficult to manage when your cities goes 50+. You can't upload again and again same script for multiple domains. I think this is not a good idea to do this. I want to use a single script for that so i can manage it in simple way.
If you have any idea than please share..
Thanks in advance
I say you how i made it:
in DNS add wildcard subdomain record
*.domain.tld. IN A 1.2.3.4
add wildcard virtualhost
<VirtualHost 1.2.3.4>
DocumentRoot /var/www/vhosts/wildcard
ServerAlias *.domain.tld.
ServerName domain.tld
...
</VirtualHost >
create a .htaccess that redirect all requests to a FrontController (usually index.php)
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
parse $_SERVER['HTTP_HOST'] from php to obtain city name and play with your new FrontController (usually index.php)
i've done it on dedicated server or VPS with linux and plesk. With some modifications on the previous basis points, it is possible everywhere;)
You can't upload again and again same script for multiple domains.
You wouldn't need to. A single web-server can support multiple domains, and files can be shared between them. See, for example, Apache's examples of setting up "virtual hosts".
Just setup a DNS wildcard so that they all go to the same site. Then using PHP you can figure out what subdomain is currently being used. Also just make sure that they all use a SESSION or COOKIE based on the domain not the subdomain if you want information to be accessible between them all.
You will also need to setup apache to accept the wildcard. So that all subdomains get directed to the same code.
$urlParts = explode('.', $_SERVER['HTTP_HOST']);
$subdomain = $urlParts[0];
Don't go the path of using Apache Virtual Hosts... While you could store scripts in a common folder and access them all via PHP (include('../common_scripts/file.php') you still have to manage the vhost configuration. Better to set up a DNS wildcard and then have a single site which takes into account the current URL when running queries.

Create sub domain using only htaccess?

I want a way to create subdomain using htaccess or any thing to do that.
I can create subdomain with change some codes in httpd.conf, but the problem I have only a host now and I can't edit httpd.conf!
You can't. The DNS name server must resolve the subdomain to the correct IP, and Apache (or whatever HTTP server you're using) must set the correct DocumentRoot for the subdomain.
Unless those two are configured properly, the request won't get to you and the htaccess would have no effect.

Dynamic .htaccess subdomain - php

I am facing small issuse with .htaccess and subdomain. To give some information, i am developing some project in php. And need to have url handled this way
My application user put their name as myname.domainname.com
they put myname.domainname.com then still i need to keep that url as it and need to call my internal file to process their data. example: i need to call myphpfile.php or any other file that i am using in application. so when any file is called from the url then i want to retrive subdomain name so that i will able to get related data
Let me know if somebody provide me simple solution. i have developed many files , now i got stucked to achieve the results.
Create a wildcard DNS entry for *.domainname.com
Create a wildcard virtual host for *.domainname.com
<VirtualHost *:80>
ServerName *.domainname.com
DocumentRoot /var/www/html
</VirtualHost>
All requests to all subdomains will go to the same document root, the same set of PHP scripts of yours.
$_SERVER['SERVER_NAME'] gives the whole host name (e.g. myname.domainname.com). If you only want the subdomain part, use:
$subdomain = preg_replace('#\..*$#', '', $_SERVER['SERVER_NAME']);

Categories