-
Notifications
You must be signed in to change notification settings - Fork 0
This tutorial will step through what MVC is, why it exists, and how CI supports it. Once this is all done, I'll have built a very very simple app (an application to show some links) - but more importantly will have explained the MVC model.
The model-view-controller (MVC) programming method is a way to split up the 3 major functions of a modern database-driven website:
- Database functions (CRUD)
- Application Logic (i.e. passwords must be 8 characters long)
- Presentation (HTML)
Each of these elements are represented by the MVC model
- Model - database
- Controller - application logic
- View - HTML pages
When it comes to MVC programming, there are some rules that need to be considered. Here are a few to help get started: Don’t do these: Views:
- Never access the database
- Never use anything more complicated than loops and if statements Controllers:
- Never contain HTML code
- Never access the database Models:
- Never ever ever spit out HTML
DO these: Views:
- Are modular - code fragments
- Contain loops and simple if logic Controllers:
- Scrub all information between the view and the database
- Provide all data needed by the view
- Applies business rules to data
- Calls database models to store/retrieve data
- Handles all errors/error messages
Models:
- Apply limited business logic - if any - to database calls
- Captures and sends any error to the controller
- Performs minimal data sanity checks
Let's start with the 'links' table in your site database. It will need the following fields:
id - autoincrement
link_title - varchar(50)
link_url - varchar(255)
Feel free to add a few sample data into the database.
Create a user for the database. Try avoiding using the 'root' (sa) account to ensure a level of security is maintained.
Using a default CI installation, open the system/application/config/database.php file:
$db['default']['hostname'] = "localhost";
$db['default']['username'] = "username"; //don't use root
$db['default']['password'] = "password";
$db['default']['database'] = "database";
$db['default']['dbdriver'] = "mysql"; //there are other drivers available!
I will assume you can configure the rest of CI, so I'm not going to discuss that. I prefer to autoload the database, so go ahead and do that.
The Model expects input from the controller the view needs a controller to be displayed the controller needs input from the view the model needs to put its data somewhere ...ugh
Here's the easiest approach that I've found:
- Build your desired HTML/CSS layout.
- De-construct the interface into the following 3 categories:
- layout - just the structure
- common data across all (most) pages:
-
- footer
-
- affiliate links/ad space
-
- stuff that changes on each page:
-
- navigation
-
- page title
-
- meta tags (keywords, description)
-
- Build your first controller that puts all the pieces back together again
- "Get dynamic" with the model, forms, and stuff...
I've gone ahead with an ultra-super-simple view. It's almost insulting; but bear with me. application/views/layout/main.php
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title><?= $title ?></title>
</head>
<body>
<h1><?= $current_page ?></h1>
<div><?= $navigation ?></div>
<div><?= $content ?></div>
</body>
</html>
You can see that there are three variables:
title - the page title
current_page - a header tag indicating the page title
navigation - a block for page navigation
content - a block for code fragments
application/views/navigation/nav_main.php
<ul id="navigation">
<li><?= anchor("","Home") ?></li>
<li><?= anchor("links","Links") ></li>
</ul>
I'm using the URL helper in that view to make my links
Finally, some content: application/views/content/link_list.php
<?php foreach($links as $link): ?>
<p><?= anchor($link->link_url,$link->link_title) ?><?= anchor('edit/'.$link->id,"Edit") ?></p>
<?php endforeach; ?>
Notice the similarity between this view and the database?
Let's use the controller to put some of it together: application/controllers/welcome.php
//function Welcome() (php4, php5 below)
function __construct()
{
parent::Controller();
$this->load->helper('url');
}
function index()
{
$data = array(
'title' => 'Test Application',
'current_page' => 'Welcome',
'navigation' => $this->load->view('navigation/nav_main','',true),
'content' => ''
);
$this->load->view('layout/main',$data);
}
Notice that I'm setting the keys of the $data array to be the same as the variable names I used in the view pages. You'll also notice that I did something special with the navigation variable - I loaded a view into it. Loading a view with "true" as the third argument returns a processed string rather than loading the view to the page. This enables multiple view pages placed into a common layout! :)
You'll also notice that I left the 'content' blank. (I'll get to that in a minute) If you were to load your page now, you will see the basic layout with the "Welcome" h1 tag and a "Test Application" web page title. There's also the navigation unordered list (one of the links won't work)
To get the list of links from the database, we need to build a model: application/models/links.php (lowercase 'L' for the file name)
<?php
//capital L for class name
class Links extends Model {
function Links() {
parent::Model();
}
function get_links() {
$query = $this->db->get('links'); //same as Select * from links
return $query->result();
}
}
?>
This model provides a simple function - get_links - to get all records from the links database we created earlier.
Now, let's update the controller: application/controllers/welcome.php
function index()
{
$this->load->model('links');
$links['links'] = $this->links->get_links();
$data = array(
'title' => 'Test Application',
'current_page' => 'Welcome',
'navigation' => $this->load->view('navigation/nav_main','',true),
'content' => $this->load->view('content/link_list',$links,true)
);
$this->load->view('layout/main',$data);
}
Now I've gotten the data from the database and put it into the $links['links'] array. At the same time, I've also loaded another view snippet into the $data['content'] array - but the second argument is the $links array instead of an empty string.
If you reload the page, you should see a list of all the links you entered into your database!
Hopefully, this helps demonstrate a means to create a model, view, and controller to display information from your database.
Feel free to add to and edit this Wiki page as you see fit :)