Creating a Simple Business Directory using CodeIgniter and MySQL

Written by sagunsh | Published 2020/04/15
Tech Story Tags: php | codeigniter | web-development | tutorial-for-beginners | php-web-development | mysql | tutorial | coding

TLDRvia the TL;DR App

A walkthrough of how to build a simple web directory using CodeIgniter and MySQL. The code is available in this github repo.

Installation

I am assuming you have PHP, MySQL and Apache installed. The easiest way to install all of these is to get XAMPP which comes packaged with Apache, MySQL and PHP. Or you can try installing each component separately.
Setting up CodeIgniter is fairly simple, go to their download page, get the latest version (3.1.11 in my case) and then follow the installation instructions. Basically all you have to do is unzip the folder into your server’s root which is htdocs for XAMPP or any custom folder if you have installed apache separately. Rename the folder to whatever name you prefer to give, in my case it’s bizdir. Don’t get overwhelmed by the lot of files and folders, we will get to them.
To verify everything is working, go to http://localhost/bizdir/ and you will see a welcome message like this

Database Setup

Create a database bizdir:
create database bizdir;
Within that database create a table directory:
create table if not exists directory
(
   id int auto_increment primary key,
   business_name varchar(255) not null,
   category varchar(255) not null,
   address varchar(255) not null,
   phone varchar(255),
   website varchar(255),
   email varchar(255),
   image varchar(255)
);
Go to application/config/database.php and set up proper configuration for your database by changing the value in $db[‘default’] array. You will need to add username, password and database.
$db['default'] = array(
    'dsn' => '',
    'hostname' => 'localhost',
    'username' => 'php_noob',       // <-- your username
    'password' => 'easy_password',  // <-- your password
    'database' => 'bizdir',         // <-- your database
    ...
    ...
    'save_queries' => TRUE
);

Here comes the code!

As I have already mentioned, CodeIgniter is a MVC framework. So we will have models, views and controllers. In simple terms, models are related to the database, view is the HTML part that you see in the browser and controller is the logic that connects your models with views. The business logic of an application lies in the controller.

Model

Let’s start by defining our models. Create a file Bizdir_model.php inside application/models and add the following code.
<?php
class Bizdir_model extends CI_Model {
    public function __construct()
    {
        $this->load->database();
    }
}
The above lines of code creates a class called Business_model which inherits the CI_Model class available in CodeIgniter. Then the constructor loads the database so you can use $this->db to access the database.
Now we need a way to insert and retrieve data. First let’s create a method get_bizdir() to get data.
public function get_bizdir()
{
   $query = $this->db->get('directory');
   return $query->result_array();
}
The function is pretty much self explanatory. Inside get_bizdir, we are getting all the data present in our directory table. It is equivalent to running the SELECT * FROM directory; query. Insert some dummy data (restaurants, hotels, banks) into the table via phpmyadmin or MySQL console.

Controller

Next we need to create a controller that loads data from our model and pass it to view. Create a file Bizdir.php inside application/controllers and add the following code.
<?php
class Bizdir extends CI_Controller {

   public function __construct()
   {
      parent::__construct();
      $this->load->model('bizdir_model');
      $this->load->helper('url');
   }

   public function index()
   {
      $data['directories'] = $this->bizdir_model->get_news();
      $data['title'] = 'Biz Dir';

      $this->load->view('templates/header', $data);
      $this->load->view('bizdir/index', $data);
      $this->load->view('templates/footer');
   }
    
   public function any()
   {
      $data['title'] = 'Biz Dir: Any Page';
      $this->load->view('bizdir/any', $data);
   }
}
Just like in model, the controller class inherits the CI_Controller class. Inside the constructor, we are calling the parent’s constructor which is CI_Controller. Then the next line loads the model which makes it accessible as $this->bizdir_model. In the index method, we are fetching all the data and putting it in $data[‘directories’].
After that, another key title is added to $data and the rest is all about passing the variable and rendering the views. The key in the variable $data will be accessible in our views as $title and $directories.
The any() method will act like a default method for any url that is not matched.

View

Now let’s create our views. Create a folder templates inside application/views and create 2 files: header.php and footer.php inside templates. Also create another folder bizdir inside application/views and create a file index.php. If you look at your controller, these are exactly the files we are loading there.
application/views/templates/header.php
<html>
<head>
   <title><?php echo $title; ?>: A complete business directory</title>
</head>
<body>

<h1 style="text-align: center"><?php echo $title; ?></h1>
application/views/templates/footer.php
<p style="text-align: center; margin-top: 10px">&copy; 2020 Bizdir. All rights reserved.</p>
</body>
</html>
application/views/bizdir/index.php
<table>
   <thead>
   <tr>
      <th>Business Name</th>
      <th>Category</th>
      <th>Address</th>
      <th>Phone</th>
      <th>Website</th>
   </tr>
   </thead>
   <tbody>
   <?php foreach ($business as $biz): ?>
      <tr>
         <td><?php echo $biz['business_name']; ?></td>
         <td><?php echo $biz['category']; ?></td>
         <td><?php echo $biz['address']; ?></td>
         <td><?php echo $biz['phone']; ?></td>
         <td><?php echo $biz['website']; ?></td>
      </tr>
   <?php endforeach; ?>
   </tbody>
</table>
There is not much going on in header and footer. In the header.php file, we are just printing the title passed from the controller.
Inside business/index.php, we are looping through the list of businesses that are in our database. One each iteration, a new <tr> is created and all the values are printed inside <td>
Create another file any.php inside application/views/bizdir and add the following HTML.
<div style="text-align: center; margin-top: 40px; padding-top: 40px;">
   <h2>This is any page</h2>
   <p>Click <a href="">here</a> to go to home page</p>
</div>
Routing
Once we have our MVC setup, we need to create routes to see specific views. Open application/config/router.php and scroll to the bottom. Replace the code with the following.
$route['dir'] = 'bizdir';
$route['dir/(:any)'] = 'bizdir/any';
$route['default_controller'] = 'welcome';
Here the key of $route appears in the url and the value on the right points to which method from a controller to call. If only the name of the controller is provided like ‘bizdir’ in our case, it will call the index() method by default. Similarly if in the url anything is present after ‘dir/’, it will call the any() method. You can learn more about routing here.
Now visit http://localhost/bizdir/index.php/dir. If everything works fine, you will see this.
As we can see the data are coming through from the database although the design is not something you will be proud of. Let’s fix the page layout and design using the magic of bootstrap.
I will be using this layout from bootstrap examples and make some customization. Feel free to use any design you like. I won’t go into much detail regarding the HTML and CSS. You can just copy paste the files from github and customize as you like if you want to.
For static files, create a folder assets inside our root folder i.e. the application and assets folder will be at the same level.
Open application/config/autoload.php and $autoload[‘helper’] = array(‘url’); at the bottom. This will make the base_url() function accessible in our views.
Inside application/views/templates/header.php add the following code right before the closing </head> tag if it is already not there.
<link rel="stylesheet" type="text/css" href="<?php echo base_url('assets/css/style.css');?>" />
The base_url() function returns the root url. Now open http://localhost/bizdir/index.php/dir to see your new home page.
Now let’s add a functionality to add a new listing to our app. In the top right corner of your home page, you can see “Add Listing” which will link us to the respective page.
First we need to add a method in our models that will insert data into the database. The data will be sent from the view and is processed by controller. Open application/models/Bizdir_model.php and inside the model class add a new method set_bizdir().
public function set_bizdir()
{
   $data = array(
      'business_name' => $this->input->post('name'),
      'address' => $this->input->post('address'),
      'email' => $this->input->post('email'),
      'phone' => $this->input->post('phone'),
      'website' => $this->input->post('website'),
      'image' => $this->input->post('image'),
      'category' => $this->input->post('category'),
   );
   return $this->db->insert('directory', $data);
}
The key of the array corresponds to the column of the table in the database. The string inside the post corresponds to the name field in HTML form. Once the values are set, the data is inserted into the directory table.
Now we need a method in our controller as well. Open application/Bizdir.php and inside your controller class create a new method add().
public function add()
{
   $this->load->helper('form');
   $this->load->library('form_validation');
   $this->load->library('session');

   $this->form_validation->set_rules('name', 'Name', 'required');
   $this->form_validation->set_rules('address', 'Address', 'required');
   $this->form_validation->set_rules('category', 'Category', 'required');

   $data['title'] = 'Add Business';

   if ($this->input->server('REQUEST_METHOD') == "POST") {
      $business_name = $this->input->post("name");
      if ($this->form_validation->run() === FALSE) {
         $business_name = $this->input->post("name");
         $this->session->set_flashdata('message', 'Error adding ' . $business_name);
         $this->session->set_flashdata('status', 'danger');
      } else {
         $this->bizdir_model->set_bizdir();
         $this->session->set_flashdata('message', $business_name . ' was successfully added');
         $this->session->set_flashdata('status', 'success');
      }
   }

   $this->load->view('templates/header', $data);
   $this->load->view('business/add', $data);
   $this->load->view('templates/footer');
}
The first 3 lines load the required libraries for forms and sessions. We will need sessions to send flash messages to our view. Then rules are set for certain fields.
The if block checks if the method is POST i.e. form is submitted. Then it validates the form and based on that create suitable messages. If the form is validated successfully, the data is inserted to our database. Finally, we will render the views. If the request method was GET, nothing inside the if block will be executed.
In your application/config/config.php file, add this line at the bottom for our session to work properly.
$config['sess_save_path'] = sys_get_temp_dir();
Finally we need a view where everything will be rendered. Create a new file add.php in application/views/bizdir and add the following code.
<?php echo validation_errors(); ?>

<div class="album py-5 bg-light">
   <?php
   $attributes = array('class' => 'form-signin');
   echo form_open('bizdir/add', $attributes);

   $message = $this->session->flashdata('message');
   $status = $this->session->flashdata('status');
   if ($message) {
      ?>
      <div class="alert alert-<?php echo $status ?> alert-dismissible fade show" role="alert">
         <?php echo $message ?>
         <button type="button" class="close" data-dismiss="alert" aria-label="Close">
            <span aria-hidden="true">&times;</span>
         </button>
      </div>
   <?php } ?>
   <div class="text-center mb-4">
      <h1 class="h3 mb-4 font-weight-normal display-4">Add Business</h1>
   </div>
   <div class="form-label-group">
      <input type="text" id="inputName" class="form-control" placeholder="Business Name" name="name" required
            autofocus>
      <label for="inputName">Business Name</label>
   </div>
   <div class="form-label-group">
      <input type="text" id="inputAddress" class="form-control" placeholder="Address" name="address" required>
      <label for="inputAddress">Address</label>
   </div>
   <div class="form-label-group">
      <input type="text" id="inputPhone" class="form-control" placeholder="Phone Number" name="phone">
      <label for="inputPhone">Phone Number</label>
   </div>
   <div class="form-label-group">
      <input type="text" id="inputWebsite" class="form-control" placeholder="Website" name="website">
      <label for="inputWebsite">Website</label>
   </div>
   <div class="form-label-group">
      <input type="email" id="inputEmail" class="form-control" placeholder="Email" name="email">
      <label for="inputEmail">Email Address</label>
   </div>
   <div class="form-label-group">
      <input type="text" id="inputImage" class="form-control" placeholder="Image URL" name="image">
      <label for="inputImage">Image URL</label>
   </div>
   <div class="form-label-group">
      <select class="form-control" name="category" required>
         <option selected disabled>Choose a category</option>
         <option>Restaurants</option>
         <option>Hotels</option>
         <option>Banks</option>
         <option>Shopping</option>
         <option>Cafe</option>
      </select>
   </div>
   <button class="btn btn-lg btn-danger btn-block" type="submit">Add</button>
   </form>
</div>
validation_errors() function will print any errors that occurred during form validation. Then the form_open() function creates a form with the attributes provided and handles security stuff like CSRF token. The next block of codes checks for any messages and prints them accordingly. Below that we have the HTML with all fields which shouldn’t be hard to understand.
Now refresh your home page and click on “Add Listing” or simply visit this url
http://localhost/bizdir/index.php/a
dd
You will see a nicely rendered form as in the image below.
Now go ahead and add data via the form. Remember we have added rules for 3 fields: name, address and category as required. Once the data is added, you will see a message saying if it was successfully added or not. If successfull, go to your home page and you will be able to see the listing.
At this point we have created a simple 2 page website to view and insert data. 
What next?
You can add a lot more functionality to this app. To start with, a simple search function would be great. Beside that, you can add features to delete and update listings. Possibly add a login/registration system that allows only authenticated users to add, delete and update the data.
I hope this article will be a good point for you to get started with CodeIgniter.
Additional Resources

Written by sagunsh | Building things with code
Published by HackerNoon on 2020/04/15