More Stupidly Easy MVC in PHP

If you've been living under a rock and missed the previous two articles about this EASY 3 class framework, go read Part1 and Part2.

After my initial project where I first created the simple framework I have since used it on 2 other projects. I didn't even use a template solution for one of them, making it even MORE simple. So I've had a chance to really collect my thoughts on this and put it through the ringer. I've had requests for more examples on using this and hopefully this will answer some of your questions.

Basically what the Stupidly Easy MVC framework does is eliminate code like this:

switch ($_POST['action']) {
	case 'saveData' : 
            saveData(); 
            break;
 	case 'deleteData' : 
            deleteData();
            break;
	case 'showForm' : 
            showForm(); 
            break;
	default:
	    showForm();
}

And saveData, delData, showForm, showConfrimMessage are all function that either do database work such as saveData, deleteData or display a form or message as in the case of showForm, and showConfirmMessage. I used to always program this way. Not bad huh? if I had only 2 or 3 actions, then I might write an if/else statement rather than a switch.

So in the case of this example when the user first goes to the page, there is no $_POST['action'] set, so it would use the default action of showForm.

In the Stupidly Easy MVC framework, we would have three files. Contact_Controller.class.php Contact_Model.class.php, and Contact_View.class.php. Then of course, an index.php (or whatever) file that is used in the URL.

Attention Control Freaks!
For the Controller we'd have this

class Contact_Controller extends MVC_Controller
{
    function Contact_Controller() 
    {	
        parent::MVC_Controller();
	$this->view = new Contact_View();
	$this->model = new Contact_Model();
	$action = $_REQUEST['action'];

	$this->do_action($action);
    }

    function default_action()
    {
	$this->showForm();
    }

    function saveData()  
    {
	// Model class has method saveData which validates
	// and saves the data 
	$this->model->saveData($_POST);
	$this->showConfirmMessage('Data has been saved');

    }
}

Do YOU know where your Data is?
The model is basically its just methods that return data as arrays. You could also load data from an xml file, csv file, call a random text generator (useful for faking emails from management) or whatever! The actual mechanics of getting the data is hidden from the actual use of it. I really like having all database statements in one file. Then when the genus who originally developed the database designs to change "fname" to "first_name" you know where your SQL is. It could also be used for that person that insists on managing their database with an Excel spreadsheet (don't laugh, true story). I can put the implementations on getting the data in here and other code will be none the wiser. All it knows is if passed getContact an id, then array of data is returned.

class Contact_Model extends MVC_Model
{
	function getContact($id) 
	{
	// return array of data
	}
}

Originally, I had the model with hooks for storing the DB ref and a method to get an db ref as an array, however I think one should extend the empty MVC_Model and then add the hooks they want. I had to change the base class for both of my applications. Which is fine, since they were on totally different systems.

From My Point of View
For the View in previous articles when I used smarty it looked like this

function showForm()
{
$this->view->assign('data',$_POST);
$this->view->display('showForm'); //showForm is name of templates  
}

But, for my second application I didn't need a template system. It was just a few forms. It was simple enough that I just did something like this in my view class.
In the controller we have:

function showForm()
{
    $this->view->showForm($_POST);  
    //yes, I could access post within, but  I'd rather not
    //if I am going to access a global variable I want to do it only on the main page
}

And in the view:

class Contact_View 
{
	function showForm($data)
        {
		$this->_showHeader();
		?>
		<form action='<?=$_SERVER['SCRIPT_NAME']?>' method='post'>
		<input type='hidden' name='action' value='saveData'>
		Name: <input type='text' name='contact_name'>
		Phone: <input type='text' name='contact_phone'>
		<input type='submit' value='Save'>
		</form>
		<?
		$this->_showFooter();
	}

	function _showHeader($title = "Contacts")
	{
		?>
		<html><head><title><?=$title;?></title></head>
		<body>
		<?
	}
	function _showFooter()
	{
		print "</body></html>";
	}
}

You could also easily convert your functions in the View to use a template later on, when this simple project your boss wanted becomes a monster (another true story).

Notice the hidden variable 'action' in the form is actually the exact name of the method you want to call when the form is submitted. Using convention such as that eliminates the spaghetti code I talked about at the beginning of this article. If the method does not exist, then the method nonexisting_action is called displaying a message to the user. You may want to overwrite this in your controller to display a different message or call the default_action method.

Then in index.php page all you need is

include_once('Contact_Controller.class.php');

$c = new Contact_Controller();

And that’s it. the constructor either calls the method specified in the 'action' variable or calls the default_action method. And that’s really all there is to it.

Any suggestions? has anyone tried this yet?

oh sorry that should say

oh sorry that should say View not model. hehe. I'll fix it!

common elements

Hmm, I think I would put comment elements in a template. Take Codesnipers, you have the same content on the left and right panels, ok so that would go in the template. The center pane changes depending on if you are reading a blog entry, writing a blog entry or writing a comment.

In Smarty, you can include a template in a template, so you can have your page.tpl and then include either content_add_blog.tpl or content_add_comment.tpl etc.

With my second method of embedding the html in the View method, I have a method _showFooter() _showHeader() where I would put the common elements. Then basically in each of my view methods, I call the _showHeader, then display the content for this page and _showFooter.

Does that help? Maybe I'll write an article to explain with more examples if you think that would help.

watch for another article

Watch for another article, I'll try and explain how I would structure the site and have multiple controler/models (I'm learning as I go too!)