Write your own MVC with PHP

this is the best MVC tutorial I came across so far,
http://php-html.net/tutorials/model-view-controller-in-php/

I am new to MVC and I am still confused with the class Model and the class book in the example of that tutorial…

for instance, I have my website and the content of my webiste is pulled from a database… so when I request a specific page for instance, http://www.mysite.com/index.php?pg=profile or with clean url http://www.mysite.com/profile

so usually, I will get the content from the SQL query,

$sql = "
SELECT * FROM root_pages
WHERE root_pages.pg_url = ‘“.$_REQUEST[‘pg’].”’
";

so then should this $sql be put in the book class or model class??

or this should be in the controller class actually? :shifty::shifty:

I have a directory folder which keeps all my CMS files, which contains update, insert, delete SQL queries, html forms, and pages that display the db items into lists, etc.

so if I implement MVC on my website, then I am going to relocate these CMS files into different locations, like some in the model folder, and some in view folder and others in controller folder, is it correct??

many thanks,
Lau

My own interpretation of MVC is (it may or maynot be technically correct but works for me):

  • Model Class: Contains all the queries, each function is one query, the return value either being the results or true/false depending on if the query run ok (mainly for updates and inserts).
  • View Class: I’ve recently changed how I do the view, now each function in the view class corresponds to a screen, the contents are concatenated into a string which is passed to the template for display, some of the information is grabbed from the model and/or controller as needed. Very limited processing (limited to checking if any results have been returned by a model, displaying one thing (usually something like “No matches found”) or displaying the results as needed.
  • Controller Class: This does all the processing such as calculations passing data to and from model classes as needed.

I use a single instance of a database class object which gets handed around to whichever model class needs to access the database.

thanks for sharing your practice, what is a single instance of a database class object?

The index.php page creates an instance of the database object, that database object is then passed (Aggregation) to both the page view and page controller classes via their constructors, the page view and page controller classes then pass (again via aggregation) to the view and controller objects respectivly. Both the view and controller objects create new instances of the model objects that they need, the model objects are passed the database object via their constructor.

This keeps the number of open database connections at the same time down to a minimum (1 unless there is a problem) and cuts out the overhead of opening multiple database connections. I’ve also just switched the session management over to using the database.

There may well be people who think that is the wrong way but that’s the way I do it and it works for me.

That’s not strictly true

The View recieves user input, which (in the context of web applications) is generally passed to the Model via the Controller.

The Controller is little more than a traffic cop that co-ordinates the show.

The topic of what the M in MVC means is pretty huge. First, you need to understand “the domain”. The domain is the real world system you are “modelling” in your application, and your Model needs to embody this.

So, if you were creating an app for air traffic management, you’d need Model classes to represent each of the entities in the system - i.e Employees, Passengers, Aeroplaines, Airports. Then you’d need Models to represent other, less easily discerned aspects of the domain, like Flight Plans, Accidents etc. Some of these elements might be what is called a Service - this code doesn’t represent an object, but rather a service to help two Entities in your system interact. So, that’s the basic concept of a Model, it embodies the BUSINESS LOGIC of the DOMAIN. The how is the next part.

Model classes that are just OOP wrappers for database interaction are what is called “anemic domain models”. Generally speaking, OOP wrappers around SQL calls are known as Transaction Scripts - they provide a convenient API for the Database Abstraction Layer (DBAL). There’s nothing wrong with this approach, but it’s not the true meaning of a Model (IMO). All object oriented methods for handling database interaction can be grouped under the term Data Access Objects - but just as all Dogs are Animals, not all Animals are Dogs. Within the field of Data Access objects, there are two principal patterns that you will see again and again.

The first is Active Record (much loved by Ruby enthusiasts) in which each object in your system represents a 1:1 relationship with a table in your database. Some AR systems de-normalise data in their tables to allow for more complex objects to map to tables. The pattern is really simple, and it’s easy to see why it’s so popular.

The other main pattern is Data Mapper (which comprises the core unit of Domain Model). DM aggregates data from several disparate tables, and “hydrates” the data into an object in your system. A Rich Domain Model will be able to handle generation of complex object graphs - objects which contain other families of objects and so on. The term ORM (Object Relational Management) relates to both patterns in practice, but in principle I think it only really applies to Data Mapper - since that pattern handles data relations more explicitly than Active Record.

Confused? No problem - it is very confusing! There is a lot of controversy around the validity of ORM systems. OOP is intended to make code human readable - to embody human domain concepts in code. ORM’s are an attempt to bridge the gap between that style of coding, and the relational nature of databases - with mixed degrees of success. One could argue that forcing OOP paradigms onto RDBMS is not a great use of code (much like forcing classical OOP paradigms into Javascript)

My advice - create DAO’s that embody your most common SQL transactions as functions. Then, create entities that can utilise these DAO’s to embody behaviours. So a User object would have a Data Access class within it to handle CRUD stuff, but would also contain a bunch of methods not specific to data interaction.

Hope that helps

Couple of points here:

It’s probably easier from both a development and readability for Active Record
to handle complex objects (think $user->orders[1]->items[0]->product->name). The same can be achieved with Data Mapper, but there are more issues to overcome.

On 1:1 mappings, I’d argue that if your database is designed sensibly to start with, a 1:1 object:table mapping is inevitable in most cases, even desired.

As for MVC, you’re right it’s a layer in the system and contains all the business logic. However, it almost certainly cannot be represented by a single class. It will contain the business logic (which is often wrongly put in the controller) that accesses and manipulates entities within the system. All the data mappers, entities and business logic are part of this Model layer.

One other thing I’d like to add here is that unlike some frameworks would have you believe (CakePHP i’m looking at you) there’s no need for each controller to have a specific related model.

For sure, I’m not advocating DM over AR. The more research you do into a Rich Domain Model, the more of a pain in the ass it seems to be (relative to a straightforward transaction script). Why go to such extraordinary lengths to hide the data store? ORM syntax often ends up being as verbose as a straight query!

hmmm - While certainly desirable from the perspective of the ORM, I’m not sure you could maintain proper database normalisation.

Sorry, that wasn’t what I was implying - the Model layer is indeed comprised of many Domain Objects (Model classes) and Services/Logic components to help with their interaction. This is the trouble with the M part of the MVC concept - the Model is a massive subject, the VC layer simply serves to expose the Model via the web interface. So easy to wrap up that particular headache in the DBAL acronym…

Completely - you may as well put the logic in the controller - although if you don’t successfully generate a Domain Model and fall back on Transaction Scripts you start to see something like that emerging - Model classes simply serving to delegate business logic out of the Controllers and becoming define by the actions/commands they correspond to, rather than the Domain component they represent.

@lauthiamkok To bring it back down to earth - the Model can be as complex or as simple as you want, although you may find that what is simple at the beginning yields greater complexity at the end.
The patterns discussed here are not vital to implementing a Model. They are just methods people have established in the past that have yielded a productive API. In layman’s terms, the M in MVC is the part of your application concerned with doing the heavy lifting i.e. working out prices, getting records, updating records blah blah blah. The V and the C are simply the mechanism for interacting with it (which is where pre-rolled frameworks help).

One example is form validation - some people advocate putting validation in the form itself, other people who prefer the ORM route put the validation in the Domain Objects. In practice, it’s a bit simpler to put that stuff in the forms, but it’s not as elegant. The point is, either way will work! That’s why it can get confusing, there’s a lot of ways to skin the MVC cat - but that’s where the “design” part comes into play - it’s almost an aesthetic choice.

Can you provide a real world example? The ORM will need to handle relationships anyway so as long as the relationships are set up I fail to see how keeping the entities 1:1 is an issue, even when tables are linked one-to-one. For example the classic order item - product link. What’s wrong with doing $order->items[0]->product->name; rather than $order->items[0]->productName; I can’t see any real benefit in the latter, it’s just combining multiple records into one entity.

Completely - you may as well put the logic in the controller - although if you don’t successfully generate a Domain Model and fall back on Transaction Scripts you start to see something like that emerging - Model classes simply serving to delegate business logic out of the Controllers and becoming define by the actions/commands they correspond to, rather than the Domain component they represent.

This is somewhere I’ve been struggling recently and had to do pretty much exactly this in some places…

The problem is, where an action is affecting multiple entities, e.g. a “add reply” to a forum topic type scenario.

There’s a lot of logic here which has no clear place to put it:
-the new post needs to be added.
-a list of users who have asked for email notification of replies needs to be fetched
-an email needs to be sent to those users

All of this could be done in the controller, but then it’s not reusable.

Should the logic be put into the save routine (be it part of a mapper or on the Reply object itself in the style of active record)? This presents more problems:

-It couples the Reply mapper to the User mapper so it can find the users
-It couples the Reply mapper to the E-mailing script
-It gives a save routine the ability to send out mails (!) this should not be desired functionality as it is not clear to anyone looking at the code. If I call $mapper->save($data); it should do only that. It’s not very OO having a method perform multiple actions.

So what’s the alternative here? I just did exactly what you said above, moved the logic into its own class so that it’s not in the controller, which gives me only re-usability as an advantage of having it in the controller. It does seem wrong, but so do the alternatives I can think of.

Thanks for explaining this! :slight_smile:

Thanks for this reply. There are a lot to take in! lol

What does DAO stand for btw?

Thanks! :slight_smile:

1: I personally wouldn’t advocate building your own ORM unless
a) it’s for academic interest
b) you’re a sucker for punishment
c) you have a genuine new twist on the ORM concept

2: As far as real world examples are concerned, I’d check out Redbean or Doctrine 2 (when it’s launched). The former is built more along the Active Record lines, the latter seems to have more Data Mapper functionality.

Active Record is just simpler to implement - since the object itself takes care of database interaction - and tends to look something like this:


$User = new User(1);//denotes id in user table
$User->changeVariable($value);
$User->save;

Ideally there should be some mechanism to avoid this problem


$User = new User(1);
$User2 = new User(1); //same record, different object
$User->changeVariable($up);
$User2->changeVariable($down);
$User->save();
$User1->save();// uh oh - you just wrote a new value by accident

So you might have something like this instead to mitigate the problem. In this example, the Active Record class maintains an internal array of instantiated classes.


$User = ActiveRecord::load('user',1);
$User = ActiveRecord::load('user',2);//same object, different reference variable
$User->changeVariable($up);
$User2->changeVariable($down);
$User->save();//this will save $down
$User1->save();// no change

You would never see the users instantiated next to each other like this, but if you load the user in one part of the script, and it gets loaded again elsewhere - you can get this kind of problem.
That doesn’t even demonstrate memory management mechanisms to prevent thousands of records being hydrated into classes by default…

DAO means Data Access Object -I fell into my own trap, it’s a generic term for an object within the DBAL, Database Abstraction Layer. What I meant to say is wrap up your statements in a transaction script, and try and group them by purpose.

I often just use an abstract DAO class to contain my most common transactions (a typical Transaction Script):


select, 
selectID,
selectWhere,
selectFilter //allows for more complex queries
insert,
update,
delete. 

The main purpose of the class is to automate sql generation and quote values. Subsequent DAO classes can extend that, and add custom SQL where required. Not very pure - but pretty simple way to organise the project.

An alternative route would be to make a fluent interface class instead, with functions like select(), where(), order() so that you could dynamically build a statement using those methods instead. Zend_DB uses something like this (as well as offering Table Gateways, Row Gateways - just Google these names, they’re simple patterns to understand.)

Ultimately, you’re not honour bound to use ORM if you don’t want to, and in some cases it’s just a hindrance. Mappers, Transactions, Active Records, whatever, just pick what works for your project.

Thanks for explaining! I’m going to do further reading on these keywords (Mappers, Transactions, Active Records, ORM, DAO, etc)…

Guess it could be rather difficult for some one with the designer background like me to get the hang of it in the beginning… :slight_smile:

Thanks a lot! :slight_smile:

Hey, I just noticed you’re a janner, me too, born in Freedom Fields…
you need any help, just give us a shout. Seriously, don’t bend your head with the Model concept - it’s all a matter of how far down the rabbit hole you want to go…unless you’re working in a team or on some massive Java app, you don’t need to be a purist.

yes

and… yes

Data Access Object. Its just a class or series of class that organize data access methods. You create methods as you need them vs. having an automated system for generic tasks. With a DAO you have all the flexibility to model your domain as you choose without being tied down by automated methodology.

Here is a really simple example of a DAO used to route requests:


<?php 
/*
* Route data access layer 
*/
class DAORoute extends DAO {
	
	/*
	* @param str module name
	* @param int sites id
	* @return array route data 
	*/
	public function fetchRoute($strSitesInternalUrl,$intSitesId) {
		$strSQL = sprintf(
			"SELECT * FROM NAVIGATION_LINKS WHERE sites_internal_url = '&#37;s' AND sites_id = %s"
			,$this->_objMCP->escapeString($strSitesInternalUrl)
			,$this->_objMCP->escapeString($intSitesId)
		);
		
		return array_pop($this->_objMCP->query($strSQL));
	}
	
	/*
	* @param int navigation links id
	* @return array route data 
	*/
	public function fetchNavLinkById($intId) {
		$strSQL = sprintf(
			"SELECT * FROM NAVIGATION_LINKS WHERE navigation_links_id = %s"
			,$this->_objMCP->escapeString($intId)
		);
		
		return array_pop($this->_objMCP->query($strSQL));
	}
	
}
?>

Each method there has been written to the resolve problems at hand in a fashion that takes reuse into consideration – nothing is automated.

Yes, it’s a must to understand MVC. From your original first post. Sounds like it should be named “How to use MVC?” vs How to write your own. I for one will not write MVC framework since there are many choices to pick from. Another reason to know MVC is that it’s cross language platform. Sure~ each MVC framework has it’s own flavor but the core of MVC is same.

awww… great to know someone who is from the design/ artistic background and
knows programming languages :bouncy:

sure will keep coming here when I get stuck with these things :goof:

I am very excited in turning my php level to OOP and MVP. but I know that I cannot be a purist! lol

thanks! :slight_smile:

thanks for the opinion. I can understand your point. I know there are many frameworks out there we can use, just like there are many site builders like drupal, wordpress, etc.

my personal problem is, probably I came from the design background, I find very difficult to use wordpress and drupal after many attempts. so I aim to write my own programme to run my website and my freelance websites.

I find the CMS in wp and drupal are very over the top, one of my client hates it (wp’s), and I don’t know how to fix it when the site having an issue with wp system, so I tend to build my own CMS for myself and clients.

I have learned so much by coding every from scratch on my own! of cos, forums like this help me a lot too! :blush:

after reading so many articles from online tutorials and posts from the forum about MVC,

here is my ‘MVC’ that runs my wesite, I hope I am doing it correctly!?? :rolleyes:

the files and codes are:

index.php

<?php
include_once("config.php");
include_once("controllers/page_controller.php");
include_once("models/shared/db.php");
include_once("models/public/page_model.php");
include_once("models/public/page_entity.php");

$controller = new page_controller();
$controller -> invoke();
?>

config.php

/* Database connection details and params */
# the host used to access DB
define('DB_HOST', 'localhost');

# the username used to access DB
define('DB_USER', 'root');

# the password for the username
define('DB_PASS', '****');

# the name of your databse 
define('DB_NAME', '********'); 

page_controller.php

/**
 * This file handles the retrieval and serving of page
 */ 
class page_controller {
	public $page_model;
	
	public function __construct()  
    {  
        $this->page_model = new page_model();

    } 
	
	public function invoke()
	{
		if (!isset($_REQUEST['pg']))
		{
			//if no special page is requested, we'll show the default page to Home
			$page = $this -> page_model -> get_page('home');
			include 'views/site.php';
			//print_r($page);
		}
		else
		{
			//show the requested page
			$page = $this->page_model->get_page($_REQUEST['pg']);
			include 'views/site.php';
			//print_r($page);
		}
	}
}

page_model.php

/**
 * The page Model does the back-end heavy lifting for the page Controller
 */
class page_model {
	
	/**
	 * holds instance of database connection
	 */
	private $db;
		
	public function __construct()
	{
		$this -> db = new _db(DB_HOST,DB_USER,DB_PASS,DB_NAME);
	}
	
	/**
	 * fetch the page based on supplied request
	 * @param string $pg
	 * @return array $page
	 */
	public function get_page($pg)
	{
		//filter the request and store it in the variale
		$pg_title = strtolower(str_replace('-', ' ', $pg));
	
		//prepare query
		$sql = "
			SELECT *
			FROM root_pages
			
			LEFT JOIN root_templates
			ON root_pages.tmp_id = root_templates.tmp_id
			
			WHERE root_pages.pg_url = '".$pg_title."'
			";
	   
		//execute query	and store the array in the variale
		$page = $this -> db -> fetch_assoc($sql);
		
		//send it to the entity class and instantiate an object from it
		$page = new page($page);
		
		//return the result
		return $page;
	}
}

page_entity.php

/**
 * This is an entity class and it should be exposed to the View layer and represents the format exported by the Model view. 
 * In a good implementation of the MVC pattern only entity classes should be exposed by the model and they should not encapsulate any business logic. 
 * Their solely purpose is to keep data.
 */ 
class page {
	public $title;
	public $content_1;
	public $content_2;
	public $content_3;
	public $content_4;
	
	/**
	 * fetch the array and keep the data in varibales
	 * @param string $page
	 */
	public function __construct($page)  
    {  
        $this -> title = $page['pg_title'];
	    $this -> content_1 = $page['pg_content_1'];
		$this -> content_2 = $page['pg_content_2'];
		$this -> content_3 = $page['pg_content_3'];
		$this -> content_4 = $page['pg_content_4'];
		//print_r($page);
    } 
}

the result on the view page,

<div id="body" class="align-center">

		<?php 
		echo 'Title: ' . $page -> title . '<br/>';
		echo 'Content: ' . $page -> content_1 . '<br/>';
		?>
</div>

It works fine for me so far and I kind of like it! :rofl:

basically, my ‘MVC’ is developed from the tutorial here,

http://php-html.net/tutorials/model-view-controller-in-php/

I hope it is a good guide line for a dummy like me!

I still have another shopping cart class, do I have to re-work on it for MVC purposes??


class _store 
{ 
    // seeing is this is the only function of the store class we might as well make it static 
    public static function get_store() 
    { 
        return new SimpleXMLElement(file_get_contents(STORE_XML)); 
    } 
} 

class _product
{ 
    // public variables are evil, make it private 
    private $_product = null; 

    public function __construct($id) 
    { 
        $store = _store::get_store(); 

        foreach ($store as $product) 
        { 
            if ($product -> id == $id) 
            { 
                $this -> _product = $product; 
                // we've now found the product, no need looking through the remaining products in the XML 
                break; 
            }         
        } 

        if (is_null($this -> _product)) 
        { 
            // apperantly there is no product in the store with the given id 
            die ('Product with '.$id.' not found'); // or throw an exception, would be better 
        } 
    } 

    public function get_price() 
    { 
        return $this -> _product -> price; 
    } 
}


#shopping cart
class _cart
{
	
	 private $_contents = array();
	 private $_created;
	 
	 /**
	  * The class constructor
	  *
	  */
	 public function __construct() {
         $this->_created = time();
	 }
	 
	 /**
	  * Add a product to the cart
	  * @access public
	  * @param $productID integer
	  *
	  */
	 public function add_item($productID) {

	 	if (isset($this->_contents[$productID])) {
	 	    $this->_contents[$productID]++;	
	 	} else {
	 		$this->_contents[$productID] = 1;
	 	}
		
		//print_r($this->_contents);
	 }
	 
	 /**
	  * Remove product from cart
	  * @access public
	  * @param $productId integer
	  *
	  */
	 public function delete_item($productID) {
	 	
 		if (isset($this->_contents[$productID])) {
 			unset($this->_contents[$productID]);
 		}
	 		
	 }
	 
	 /**
	  * Change the quantity of a particular item held in the shopping cart
	  *
	  * @access public
	  * @param integer $productID
	  * @param integer $quantity
	  */
	 public function update_quantity($productID, $quantity) {
	 	$this->_contents[$productID] = $quantity;
	 }
	 
	 /**
	  * Get all items currently in cart
	  *
	  * @access public
	  * @return unknown
	  */
	 public function get_items() {
	 	return $this->_contents;
	 }
	 
	 /**
	  * How many items are in the user's cart?
	  * 
	  * @access public
	  * @return INTEGER
	  *
	  */
	 public function count_items() {
	 	return array_sum($this->_contents);
	 }

	 /**
	  * Calculate the cost of all items in the cart
	  * @access public
	  * @return float
	  *
	  */
	 public function calculate_cost() 
	 {
	 	
	 	$cost = 0.00;
	 	
	 	foreach($this->_contents AS $id => $quantity) {
	 		$product = new _product($id);
			$cost_string = $product -> get_price();
			$cost_float = "$cost_string" + 0;
			$cost = $cost + ($cost_float * $quantity);
	 		//$cost = $cost + ($product -> price * $quantity);
	 	}
	 	
	 	return number_format($cost, 2);
		//return $cost_float;
	 	
	 }
	 
}

Many thanks! :slight_smile:

thank you oddz for this… :slight_smile:

I was writing one fairly simple and figuring out how a bootstrap is written, It looks like there are several ways to go about it – I like the guy above who used invoke() and handled this through a class, I might try that but I’m just getting started so will have to see.

I am using smarty also.

index.php



/** 
*	Load Config 
*/
require_once('config/paths.php');
require_once('config/database.php');
require_once('config/session.php');

/** 
*	Load Base MVC Objects
*/
require_once('config/autoload.php');

/**
*	Check if an index() method exists in a class if no function is passed in the URI
*	@param obj $object The created object based on the URI or default with no URI.
*/
function try_default_method($object)
{
	if (method_exists($object, DEFAULT_CONTROLLER_METHOD))
	return $object->{DEFAULT_CONTROLLER_METHOD}();
	else
	return false;
}

/**
*	Handle URI (Bootstrap)
*
*	@param str $_GET Set from .htaccess
*/
if (isset($_GET['url'])) 
{

/**
*	Create array of the URL
*	@example	http://workspace/Controller/Function/Value
*/
	$url = explode('/', $_GET['url']);
	$controller	= $url[0];
	$function	= (isset($url[1])) ? $url[1] : NULL;
	$value		= (isset($url[2])) ? $url[2] : NULL;
	
/** 
*	Include the Controller and Instantiate it 
*/
	if (file_exists(CONTROLLERS."$controller.php"))
	{
		/** Create the Object */
		require_once(CONTROLLERS."$controller.php");
		
		$object = new $controller;
		
		/** See if there is a value before calling the Function	*/
		if ($function != NULL)
		{
			if (!method_exists($object, $function)) 
			{
				echo "
					<h1>Error:</h1>
					<b>function $function()</b> does not appear to be 
					inside the <b>$controller object.</b>
					";
				/** Stop PHP if the function doesn't exist */
				exit;
			}
		
			/** Load the Value if it exists */
			if ($value != NULL)
			$object->$function($value);
			
			/** Otherwise do the function only */
			else
			$object->$function();			
		}
		/**
		*	If no function declared, 
		*	look for an index function and run it by default.
		*/
		else
		{
			try_default_method($object);
		}
		
	}
	
	/** If Controller does not exist */
	else
	{
		echo "<h1>Error:</h1> The file: <b>'".LIBRARY."$controller.php'</b> does not exist.";
		exit;
	}
	
}
/** 
*	If no URL is passed in .htaccess, show a default Controller. 
*	@desc Default controller is most likely 'index'
*/
else 
{
	if (file_exists(CONTROLLERS.DEFAULT_CONTROLLER))
	{
		require_once(CONTROLLERS.DEFAULT_CONTROLLER);
		/** Remove the .php extention */
		$DEFAULT_CONTROLLER_NAME = basename(DEFAULT_CONTROLLER, '.php');
		
		/** Load the Object */
		$object = new $DEFAULT_CONTROLLER_NAME;
		try_default_method($object);
	}
	else
	{
		echo '<h1>Error:</h1> Your default controller: <b>'.CONTROLLERS.DEFAULT_CONTROLLER.'</b> does not exist.';
		exit;
	}
}

autoload.php



DEFINE ('DEFAULT_CONTROLLER',	'index.php');

/**
*	The default method to run if a method is not defined
*	@example This checks controller->index();
*/
DEFINE ('DEFAULT_CONTROLLER_METHOD', 'index');

/**
*	Autoload Libraries into main Controller/Model
*/
DEFINE ('AUTOLOAD_Database',	true);

/** 
*	Autoload Objects, Class names must match File names
*
*	@param array $sections Folders to scan for Classes
*/
function __autoload($class)
{

	/**
	* Do not neglect the trailing slash!
	* Add new subfolders here.
	*/
	$sections = array(
		LIBRARY,
		LIBRARY.'database/',
		LIBRARY.'smarty/',
		
		);

	/** Iterate: Require each Object */
	foreach ($sections as $dir)
	{
		if (file_exists($dir . $class . '.php'))
		{
			require_once($dir . $class . '.php');
			return;
		}
	}
}


paths.php


#
# MUST INCLUDE TRAILING SLASH
#
DEFINE ('CONTROLLERS',	'app/controllers/');
DEFINE ('MODELS',		'app/models/');
DEFINE ('VIEWS',		'app/views/');
DEFINE ('LIBRARY',		'libs/');

database.php


#
# Database Information
#
DEFINE ('DB_HOST',		'localhost');
DEFINE ('DB_NAME',		'********');
DEFINE ('DB_USER',		'root');
DEFINE ('DB_PASS',		'');

libs/Controller.php (The base controller)



class Controller
{

/**
*	Load Smarty and Basics
*
*	@param object get_class($this) returns the child class for loading templates
*/
	public function __construct()
	{
		$this->smarty	= new Smarty;
		$this->smarty->compile_dir = 'tmp/';
		$this->smarty->template_dir = 'app/views/';
		
		$this->child_class = strtolower(get_class($this));
		
		/** Load Database */
		if (AUTOLOAD_Database == true)
		$this->DB = new Database();

/**
*	This checks from session.php whether protected pages are on,
*	if a page is not in the unprotected list, it will check the session.
*/		
		if (PROTECT_CONTROLLERS == true)
		{
			/** Create an array to check if the child class is unprotected */
			$arrUnprotected = explode('|', UNPROTECTED_CONTROLLERS);
		
			if (!in_array($this->child_class, $arrUnprotected))
			{
				/** Do some Session checking */
				if (isset($_SESSION['userType']) == 10)
				echo 1;
				
				else
				echo 'refresh to login';
			}
		}
		
	}

/**
*	Asssign a value Short Hand to Smarty
*
*	@param str $val Assignment name to call
*	@param str $val2 Value of the Assignment
*/
	public function Assign($val, $val2)
	{
		$this->smarty->assign($val, $val2);
	}

/**
*	Smarty Function
*
*	@param str $page Use for a custom TPL to render
*/
	public function Render($page = NULL)
	{
		if ($page != NULL)
		$this->smarty->display($this->child_class .'/'.$page . '.tpl');
		
		else
		$this->smarty->display($this->child_class .'/default'. '.tpl');
	}

}

app/controllers/index.php (example controller)


<?php

class Index extends Controller
{

	public function __construct() {	
		parent::__construct();
	}
	
	public function index()
	{
		$this->Assign('intro', 'This is the home page');
		$this->Render();
	}
	
	
	public function login()
	{
		if (isset($_POST['login']) == 'jesse')
		{
			echo 'success';
		}
		else
			echo 'failure';
	}
	
	public function register($do = NULL)
	{
		
		
		$this->Assign('form', true);
		
		if ($do != NULL)
		{
			$this->Assign('form', false);
			$this->Assign('do', true);
		}
		
		$this->Render('register');
	}

}