CodeIgniter is a simple and lightweight PHP framework used to create powerful web applications. Today, we are going to do something nifty: we'll combine user names and subdomains to make for a more cohesive user experience.
If you're a bit confused, this feature allows your users to access their accounts by typing in a custom url, which maps to their user name, such as harbinger.yourapp.com
.
Overview
In this tutorial, we are going to be creating both a front-end view and a back-end application view, similar to the configuration used in Basecamp, where visiting basecamphq.com
shows the homepage, but visiting a subdomain displays the login page.
We will be using the fictional address nettutsapp.com
, and will create a sample "dashboard" page; however, you could incorporate this into an existing project with relative ease.
Before you begin, make sure that you have a web server with PHP installed. You also need to download CodeIgniter; in the example, I am using CodeIgniter 2.0, but the code should work on 1.7.2. So let's get started!
Step 1: DNS Configuration
First, we need to configure our DNS settings to make all subdomains resolve to a single address. If you are working on a live server, then you will have to change your DNS settings with the company who handles your DNS. This is most commonly your web host or domain registrar.
To cover each configuration in this tutorial would take too much time. Instead, ask your host for some help to set up wildcard subdomains. You might expect to add something like the line below to your DNS configuration.
*.nettutsappapp.com. IN A 91.32.913.343
Instead, if you are working on a local server, adding a wildcard subdomain to the hosts file is quite tricky. What I prefer to do is add single entries for testing purposes. These can be deleted after you have finished. For our domain, we need to add four entries as follows:
- 127.0.0.1 nettutsapp.com
- 127.0.0.1 user1.nettutsapp.com
- 127.0.0.1 user2.nettutsapp.com
- 127.0.0.1 user3.nettutsapp.com
Mac Hosts Configuration
To do this on a Mac, open Terminal and type sudo nano /etc/hosts
. Use the arrow keys to move to the bottom of the document, and add the entries to the bottom of the file. Once done, press Ctrl+X
and Y
to confirm the save.
Windows Hosts Configuration
If you are using Windows, browse to the directory C:\Program Files\system32\drivers\etc
and open the hosts file in Notepad, or your preferred text editor. Add four entries, shown above, and save the file.
If you've made DNS changes to a live server, it will take a while before you notice any effect. If you made changes to your hosts file, the changes will be immediate.
Step 2: Apache Configuration
The aim here is to set up two Virtual Hosts in the Apache Configuration,:one serves the front end page (Basecamp Homepage), and the other serves the page seen when accessed via a subdomain (Dashboard Page).
To add new entries, you need to open the httpd.conf
file, which can be found in the Apache installation directory. It's often found in the bin/apache/conf
folder. However, depending on your server configuration, the location may vary.
Once opened, you need to add the two entries, shown below. Be sure to change the DocumentRoot
to a location of your choice, which you have created.
Note: Remember the wildcard and the different directory path on the second VirtualHost.
WAMP Users: I recommend reading this post, which describes how to set up VirtualHosts. You may also encounter permission problems; so I recommend placing your VirtualHost directories inside the www
directory.
<VirtualHost *:80> DocumentRoot "/Users/densepixel/Sites/MAMP PRO/nettutsappfront" ServerName nettutsapp.com ServerAlias nettutsapp.com <Directory "/Users/densepixel/Sites/MAMP PRO/nettutsappfront"> Options -Indexes Options FollowSymLinks AllowOverride All </Directory> </VirtualHost> <VirtualHost *:80> DocumentRoot "/Users/densepixel/Sites/MAMP PRO/nettutsapp" ServerName nettutsapp.com ServerAlias *.nettutsapp.com <Directory "/Users/densepixel/Sites/MAMP PRO/nettutsapp"> Options -Indexes Options FollowSymLinks AllowOverride All </Directory> </VirtualHost>
Once you have saved the file, you need to restart Apache for the changes to take effect.
Make sure that you have created the directories you specified in the
httpd.conf
file before starting the server.
Step 4: Testing Our Server Configuration
Before we test the configuration, place a basic html
page in each of the directories you created earlier. Maybe add a single line of text to each, so you can differentiate them. I have copied an example for you to use.
<!DOCTYPE html> <html lang=""> <head> <meta charset="utf-8"> <title>NetTuts App Front</title> </head> <body> NetTutsApp Front </body> </html>
Next, open your favorite browser, and first check the address nettutsapp.com
. If everything works, you should be looking at the page you placed in the 'nettutsappfront
' directory.
Next, check a subdomain, eg. user1.nettutsapp.com
; this should show you the other page you created in the directory.
You can go on to check the other subdomains you specified in the hosts file, which should all show the page saved within our directory.
Step 5: CodeIgniter Installation
This tutorial assumes that you know how to install CodeIgniter. If not, you should take a look at this video tutorial by Jeffrey Way, which explains the process in detail.
Place the CodeIgniter files into our directory after deleting the html
page we created before. If you are using CodeIgniter 1.7.2, you may want to take the application
folder out of the system
folder.
Test the installation by browsing to the URL user1.nettutsapp.com
, and you should see the CodeIgniter Welcome Page.
Step 6: Setting up CodeIgniter
Set up CodeIgniter as you normally would, as described in this tutorial. You may want to remove the index.php
from the URL, autoload some libraries or helpers, etc. For the purposes of this tutorial, we need to autoload the database
library and the url
helper. Open the autoload.php
file in the config
directory, and add the relevant entries.
We also need to change the default controller to one which we will be making, called dashboard. This value can be changed within the /config/routes.php
file.
Base_url
For the user subdomains, we need to make the base_url
variable dynamic, as the application will be receiving requests from a number of potential subdomains.
The easiest way to do this is by using the HTTP_HOST variable. Open the config.php
file, and find the variable $config['base_url']
, and replace it with the following code:
if(isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == "on"){$ssl_set = "s";} else{$ssl_set = "";} $config['base_url'] = 'http'.$ssl_set.'://'.$_SERVER['HTTP_HOST'];
This code allows for HTTPS
connections, however, if you never plan on using HTTPS
, you can simplify it to base_url = $_SERVER['HTTP_HOST']
.
Database Settings
Before we go ahead and add the database settings into our CodeIgniter application, we need to create both the database and a sample table.
This example application uses one database and one table. This table will hold all the subdomains currently assigned, and some basic information about them. If you've decided to use this code in your own application, you'll have to generally assign multiple users to a single subdomain, however that database schema is beyond the scope of this tutorial.
The table is named nt_subdomains, within the database ntapp, and has four fields:
- subdomain_id(primary, auto_increment)
- subdomain_name
- user_fname
- user_sname
I have also populated the table with two records, which match the subdomains we've added to our hosts file:
Now we can open the database config, file found in /application/config/database.php
, and edit the following values so that they match your personal configuration settings.
$db['default']['hostname'] = 'localhost'; $db['default']['username'] = 'root'; //MAMP default $db['default']['password'] = 'root'; //MAMP default $db['default']['database'] = 'ntapp';
And we're done setting up our CodeIgniter installation. Let's start using the subdomains in our application.
Step 7: Creating Our Controllers and Views
For this application, we are going to create two controllers. The first is an error
controller, which displays an error if the subdomain has not been registered for use in the application. The other controller is our main dashboard controller, which is what the user sees if the subdomain has been added to our database.
Error Controller
Let's go ahead and create our error controller. First, create a new file in the /application/controllers
directory, and call it error.php
.
Note: The name of the file is important
<?php class Error extends Controller { function Error() { parent::Controller(); } function index() { $this->load->view('error'); } }
Add the code above to our new error.php
file. The index
function loads a view called 'error
', which we will be creating later.
Dashboard Controller
Now we need to create the main dashboard controller, which will be loaded when a user enters one of the subdomains. The controller will then check whether the subdomain has been registered, and will redirect as necessary. We'll add this code later, but first, we need to create the basic controller.
Create a new file within the controllers
directory, and name it dashboard.php
. Within this file, we need to create the controller and load the dashboard view. Copy the code below and save the file.
<?php class Dashboard extends Controller { function Dashboard() { parent::Controller(); } function index() { $this->load->view('dashboard'); } }
Error View
The error page will be displayed when a user tries to access a subdomain, which has not been registered for use by the application. For the purposes of the tutorial, simply create a basic page, displaying the message Subdomain Not Registered. Add the code below to a new file called error.php
and save it within the application/views folder.
<html> <head> <title>Application Error : Nettuts App</title> </head> <body> <h1>Nettuts Application Error</h1> <p>Subdomain Not Registered</p> </body> </html>
Dashboard View
For the time being, we will only be creating a basic dashboard page. You can use the same structure as the error view, and just change it to read Nettuts Dashboard, or something along those lines. Save the page as dashboard.php
, within the application/views
folder.
Test the two views by visiting the URLs:
- user1.nettutsapp.com/index.php/error
- user1.nettutsapp.com/index.php/dashboard
Working? Let's move on.
Step 8: Extending Our Dashboard Controller (Part 1)
The next step is to extract the subdomain name in our controller so we can use it in a database query.
We are going to insert our subdomain checking code into the construct
function within the dashboard controller. (Underneath the parent::Controller()
). This means that the subdomain will be checked when any of the functions within the dashboard controller are accessed.
The easiest way to extract the subdomain name is to use the PHP explode
function, and set the delimiter to '.'. As we only need the first part, we can split it into two parts, and then assign the first part (the subdomain name) to a variable.
To test this, we can echo
the variable out in the controller itself. See the code below:
<?php class Dashboard extends Controller { function Dashboard() { parent::Controller(); $subdomain_arr = explode('.', $_SERVER['HTTP_HOST'], 2); //creates the various parts $subdomain_name = $subdomain_arr[0]; //assigns the first part echo $subdomain_name; // for testing only } }
Access your subdomain URLs, and you should see the correct subdomain echoed on your page, as below.
Note: You can delete the echo statement now.
Now that we have access to the subdomain name in our controller, we can check to see if it has been added the table we created earlier.
We will be using CodeIgniter's ActiveRecord Class to build our queries, which will check the table for the accessed subdomain. If it is present, then the user will be able to access the dashboard page. If, on the other hand, the subdomain has not been entered, then they are denied access, and are then redirected to the error page we created earlier.
For this tutorial, we won't be using models as it makes the tutorial much easier to follow. CodeIgniter is quite flexible in that it doesn't force you to use them.
First, we need to assemble the query as show below. This code will only work in PHP5, as it uses method chaining; however, you can change it to your liking.
// adds on from rest of construct // $this->db->from('nt_subdomains')->where('subdomain_name', $subdomain_name); $query = $this->db->get();
We can use the CodeIgniter function row()
to check whether that subdomain exists in the table. If it doesn't, then we need to use the redirect function to redirect our users to the error controller. The next part of the code is below:
// adds on from previous code // if($query->num_rows() < 1) { redirect ('error'); }
Let's test this by accessing user1.nettutsapp.com
, which should direct you to the dashboard page. Now, try user3.nettutsapp.com
, which should redirect you to the error page as it was not entered into the table.
Step 9: Extending Our Dashboard Controller (Part 2)
Now we can use the information in the table to display specific information for each subdomain.
We'll add to the index
function in our dashboard controller. First, copy the subdomain name code and the database query we used before.
function index() { $subdomain_arr = explode('.', $_SERVER['HTTP_HOST'], 2); $subdomain_name = $subdomain_arr[0]; $this->db->from('nt_subdomains')->where('subdomain_name', $subdomain_name); $query = $this->db->get(); }
We are using CodeIgniter's row()
function to retrieve the result of the query. The row
function returns a single result row, which means we don't need to use a foreach
loop; it's unnecessary.
// adds on from rest of index function // $subdomain_info = $query->row();
Then, assign the user_fname
and user_sname
column values to the array
, $data
, which is then passed to the view
.
$data['fname'] = $subdomain_info->user_fname; $data['sname'] = $subdomain_info->user_sname; $this->load->view('dashboard', $data);
We can use these values within our view by using the variables $fname
and $sname
. Open the dashboard view and edit it to read:
<p>Welcome to your dashboard <b><?php echo $fname; ?> <?php echo $sname ?></b> </p>
And we're done! Let's test it.
Step 10: Testing
Try all of the URLs, and hopefully, if everything went according to plan, the results should be as follows:
- nettutsapp.com → Front End Page
- user1.nettutsapp.com → Dashboard (John Doe)
- user2.nettutsapp.com → Dashboard (Steve Smith)
- user3.nettutsapp.com → Error Page
Controller and View Code
Here's the complete cote used for our controllers and views:
Dashboard Controller
<?php class Dashboard extends Controller { function Dashboard() { parent::Controller(); $subdomain_arr = explode('.', $_SERVER['HTTP_HOST'], 2); $subdomain_name = $subdomain_arr[0]; $this->db->from('nt_subdomains')->where('subdomain_name', $subdomain_name); $query = $this->db->get(); if($query->num_rows() < 1) { redirect ('error'); } } function index() { $subdomain_arr = explode('.', $_SERVER['HTTP_HOST'], 2); $subdomain_name = $subdomain_arr[0]; $this->db->from('nt_subdomains')->where('subdomain_name', $subdomain_name); $query = $this->db->get(); $subdomain_info = $query->row(); $data['fname'] = $subdomain_info->user_fname; $data['sname'] = $subdomain_info->user_sname; $this->load->view('dashboard', $data); } }
Error Controller
<?php class Error extends Controller { function Error() { parent::Controller(); } function index() { $this->load->view('error'); } }
Dashboard View
<html> <head> <title>Dashboard : Nettuts App</title> </head> <body> <h1>Nettuts Dashboard</h1> <p>Welcome to your dashboard <b><?php echo $fname; ?> <?php echo $sname ?></b> </p> </body> </html>
Error View
<html> <head> <title>Application Error : Nettuts App</title> </head> <body> <h1>Application Error</h1> <p>Subdomain Not Registered</p> </body> </html>
Conclusion
Of course, this tutorial describes only one way of obtaining this nifty functionality. I'm sure there are many more; so feel free to chime in with your thoughts and opinions in the comments section below.
Comments