PHPWomen Site Home » Programming » Best Practices » MVC alternative for simple projects.
MVC alternative for simple projects. [message #2140] Tue, 29 July 2008 20:07 Go to next message
madpoet  is currently offline madpoet
Messages: 1
Registered: July 2008
Shiny and New
MVC (Model-View-Controller) is a common pattern for software applications. In simple projects I prefer a different organization which have the MVC characteristics.

What you'll see in this article are:
- Alternative PHP coding style to use within HTML.
- Using both GET and POST methods together within the same HTML form
- HTTP redirection method to avoid reposting data when the page is refreshed after insert/update/delete.
- Flash messages using sessions for HTTP redirection method.
- An example of call_user_func()


Let's take a simple CRUD operation as an example. (CRUD: Create - Read - Update - Delete)
Think about a simple e-mail addressbook. We have the list of friends. Friends can be edited, deleted, or a new friend can be added.


The Files

lib/common.php:
All common tasks like authentication, db connection, session, configuration etc. are defined in this file.

lib/functions.php:
Global functions in here. Required in common.php.

index.php:
This is the page where people are listed. This file is organized as a template.

form.php:
The form for the update and insert action. This file is organized as a template.

header.php and footer.php:
Obvious.

post.php:
insert, update, delete actions are in this file.
This file is only accessed with POST. (In this example deletion is sent via GET method for simplicity)
After every action, the page is redirected to index.php by HTTP header. So if the user refreshes the page after inserting or updating or deleting,
they would never see the annoying "do you want to resend the data" confirmation message.


File Contents

header.php and footer.php are obvious I think, so I skip them.

index.php:

<?php
require("lib/common.php");

/**
 * All bussiness logic is at the beginning of the file.
 * Think it as the Model, but not in a seperate file.
 */ 
$users = $db->fetchAll('select * from people');

/**
 * The rest is formatted as a template. Think it as the View...
 * For easier reading alternative formatting of php is used so that indentation
 * of HTML and php code are not messed up.
 * No extra PHP codes below, only loops, if/else statements and formatting functions 
 * are allowed as in common template systems.
 */
?>
<? include('header.php');?>


<? if($_SESSION['flashMessage']):?>

  <div id="flash">
  <?=$_SESSION['flashMessage'];?>
  <? unset($_SESSION['flashMessage']);?>
  </div>

<? endif;?>



<? if($users):?>
  <ul>
  <? foreach($users as $user):?>
    <li>
    <?=$user['name'];?> 
    <span class="action">
    <a href="form.php?id=<?=$user['id'];?>">Update</a> | 
    <a href="post.php?cmd=delete&id=<?=$user['id'];?>" onclick="return confirm('Are you sure?');">Delete</a>
    </span>
    </li>
  <? endforeach;?>
  </ul>
<? endif;?>

<p><a href="form.php">New User</a></p>

<? include('footer.php');?>




form.php

<? 
require("lib/common.php");

/**
 * If id is sent then update the data. Else it's a new user
 */
if(is_numeric($_GET['id'])) {
  $user = $db->fetchRow('select * from people where id = '.$_GET['id']);
  $cmd = 'update';
} else {
  unset($_GET['id']); // Avoid XSS
  $cmd = 'insert';
}

// Here comes the View!
?>

<? include('header.php');?>

<!-- We may use GET and POST methods together. Only POST necessary values for update. Send other values via GET -->
<form action="post.php?cmd=<?=$cmd;?>" method="post">

<input type="hidden" name="id" value="<?=$_GET['id'];?>">
<input type="text" name="name" value="<?=$user['name'];?>">
<input type="submit">

</form>

<? include('footer.php');?>



post.php

<? 
require("lib/common.php");

/**
 * Smt. like a controller
 * You may easily extend this file by simply adding a 'case' and
 * the function with the same name.
 */
switch($_GET['cmd']) {
  case 'insert':
  case 'update':
  case 'delete':
     call_user_func($_GET['cmd']);
     break;
}

/**
 * Start actions
 */
function insert() {
  // Do the insert
  ...
  
  redirect_to('index.php', 'User added');
}

function update() {
  // Do the update
  ...
  
  redirect_to('index.php', 'User edited');
}

function delete() {
  // Do the delete
  ...
  
  redirect_to('index.php', 'User deleted');
}



functions.php
/**
 * This function makes an HTTP redirect. The message is stored in session
 * so that it can be shown in the redirected page.
 * After it's shown, the message is cleared. (See: index.php)
 */
function redirect_to($url, $msg) {
  $_SESSION['flashMessage'] = $msg;
  
  header("Location: $url");
  exit;
}



One step forward of this structure is adding an external template system like smarty or savant. In that case index.php and form.php would act like model, template files will be the views.

And if you want to get closer to MVC even further, try Zend Framework!

Enjoy...

[Updated on: Tue, 29 July 2008 20:26]

Re: MVC alternative for simple projects. [message #2151 is a reply to message #2140 ] Thu, 31 July 2008 14:31 Go to previous message
coche  is currently offline coche
Messages: 17
Registered: July 2008
Location: El Salvador
Shiny and New
madpoet, I think is a good approach of yours. Thanks

I prefer Rasmus MVC approach rather than Zend's Framework.

[Updated on: Thu, 31 July 2008 14:31]

Previous Topic:Flash Your Errors: It's Illegal In 28 States!
Next Topic:Preventing data being inserted twice - the safe and easy way
Goto Forum:
  


Current Time: Fri Jul 30 13:03:19 EDT 2010

Total time taken to generate the page: 0.00989 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.0.
Copyright ©2001-2006 FUD Forum Bulletin Board Software