/    Sign up×
Community /Pin to ProfileBookmark

Looking for MVC tutorial

Hi there,

I’ve been trying to learn OOP and I get it I think but I really want to understand the MVC way of OOP as it seems to make a lot of sense to use that, but I generally don’t understand how to separate them completely. So I was hoping someone (like nog_dog who seems to know everything i want to) could point me in the direction of something thoroughly explaining MVC and how to plan for this approach in a project.

Thanks much in advance!

to post a comment
PHP

10 Comments(s)

Copy linkTweet thisAlerts:
@NogDogMar 30.2011 — You can see one implementation of it in action with the CodeIgniter video tutorials.
Copy linkTweet thisAlerts:
@DerokorianauthorMar 30.2011 — I watched that actually, I guess I just dont understand how to approach the separation, I already separate the layout from the content. IE this is my index.php:
[code=php]
<?
// Always start session first
session_start();

// Setup variables
include("./includes/variables.php");
include($admininc."functions.php");

// Connect to database
$db = new mysqli($dbhost,$dbuser,$dbpass,$dbname);
if( mysqli_connect_errno() ) {
echo "Connection to database failed: ".mysqli_connect_errno();
exit;
}

// include content file
if ( ISSET($_GET['action']) ) {
$action = trim($_GET['action']);
if( $action == "logout" ) {
unset($_SESSION['userid']);
session_destroy();
$content .= "You have been logged out.<br />n";
header("refresh:2;url={$adminurl}");
} else {
// User Session
$login = checkLogin();
if ( ISSET($_SESSION['userid']) ) {
if( ISSET($_GET['page']) ) $page = $_GET['page'];
include("{$admininc}{$action}.php");
} else {
$content .= "You must be logged in to view this area.<br />";
}
}
} else {
// User Session
$login = checkLogin();
if ( ISSET($_SESSION['userid']) ) {
$content .= "You are logged in, please select an action.";
} else {
$content .= "You must be logged in to view this area.";
}
}

$db->close;
// Print page
include($admininc."header.php");
include($admininc."nav.php");
echo "<div id="main">n{$content}</div>n";
include($admininc."footer.php");
[/code]


However the reason I feel I dont fully understand it, is because then my content files would be setting the content variable with the formatted output... ie
[code=php]
switch($page) {
case "gal":
// Add Gallery Form
$content .= "<h1>Add Gallery</h1>
<form action="{$adminurl}?action=gallery&amp;page=galsub" method="post">
<label for="galname">New Gallery Name</label><input type="text" name="galname" />
<label for="submit">&nbsp;</label><input type="submit" name="submit" value="Submit" /><input type="reset" value="Reset" />";
break;
case "galsub":
// Add Gallery Processing
$galname = sqlSafe($_POST['galname']);
$galsql = "INSERT INTO {$dbgallerytable} (idgallery,gallery_name) VALUES (NULL,'{$galname}')";
if( $db->query($galsql) ) {
$content .= "<p>$galname was added to the gallery listing, please make sure to add an album and some pictures.</p>";
} else {
$content .= "<p>Gallery: $galname failed to be added.</p>";
}
break;
}
[/code]


My understanding is that should actually output some thing to variables or objects that gets sent somewhere else to be utilized and formatted. But I dont understand how to get that last level of separation.
Copy linkTweet thisAlerts:
@DerokorianauthorMar 30.2011 — I guess that was a bad example, but they all say view doesn't do any database usage, controller never access database never use html, model accesses database doesn't sanitize data doesn't return html... but that to me feels like I'm writing mysql query in a different file just cause... then what the model turns that into an array instead of a result? then how does the controller change it without adding any html markup?
Copy linkTweet thisAlerts:
@NogDogMar 30.2011 — You are writing the query in one separate place both for general re-usability issues, as well as for a compartmentalization of responsibility (both key aspects of OOP in general). Similarly you are outputting HTML only in the view for essentially the same reason, allowing you to completely change the actualy HTML and the site's layout without having to touch the controller or model code. So a controller might call a model which returns a data set that the controller puts into an array, then decides which view to use and includes/requires it, and that view makes use of that array to populate some dynamic part of its output.

If you are creating a 3-4 page site that maybe does 1 or 2 queries per page, maybe it's not a big deal to change any aspect of the site. If that expands to 30-40 pages with dozens of different potential database actions and several different business logic flows, suddenly that compartmentalization becomes extremely useful and prevents a lot of potential headaches in terms of testing, debugging, maintaining, enhancing, and so forth.

Anyway, I don't personally care to deal with a lot of the details of implementing a MVC application, which is why I use CodeIgniter in those cases where I feel it's warranted to take such an approach.
Copy linkTweet thisAlerts:
@DerokorianauthorMar 30.2011 — Ok so the user wants to see the personA's posts for the last week the MVC model would then be, as follows? (yes, no, maybe) [code=php]
//controller
include("recentpost.php");
$posts = recentpost($id,$duration);
include("postlayout.php");
postLayout($posts);

//model
function recentpost($id,$duration) {
GLOBAL $db;
$lasttime = time()-$duration;
$sql = "SELECT * FROM post WHERE user=$id AND postdate>$lasttime";
$result = $db->query($sql);
foreach($result as $key=>$value) {
$post[$key] = $value;
}
return $post;
}

// view
function postLayout($posts) {
echo "<table>";
foreach( $post as $key => $value) {
echo "<tr><td>$key:</td><td>$value</td></tr>";
}
echo "</table>";
}[/code]


Also I understand this code may be symantically wrong, I just wrote it in the reply box heh... you get the idea.
Copy linkTweet thisAlerts:
@NogDogMar 30.2011 — Here's a sketchy, buggy, skeletal view on how you *might* approach it:

index.php:
[code=php]
<?php
// leaving out general config/connect stuff, class auto-loader, etc....

$ctrl = new Controller();
?>
[/code]

controller.php:
[code=php]
<?php
class Controller
{
public function __construct()
{
if(!empty($_GET['user'])) {
$this->getUserInfo();
}
else {
include 'default_view.php';
}
}
public function getUserInfo()
{
$user = new UserModel();
$data['user'] = $user->getUserArray((int)$_GET['user']);
include 'view_user.php';
}
}
?>
[/code]

UserModel.php:
[code=php]
<?php
class UserModel
{
public function getUserArray($userId)
{
// stuff here to query DB for $userId and populate array $data
return $data;
}
}
?>
[/code]

view_user.php:
[code=php]
<html>
<head><title>View User: <?php echo $data['user']['name']; ?></title></head>
<body>
<h1>Info for <?php echo $data['user']['name']; ?></h1>
<ul>
<li>Age: <?php echo $data['user']['age']; ?></li>
<!-- and so forth... -->
</ul>
</body></html>
[/code]


Most people just write their views as HTML pages, maybe using "helper" functions to handle the "boiler plate" stuff common to all pages (or just include files). You could make it a bit more OOP by putting the data used by the view into some sort of object, maybe including some general methods for outputting a selected data set in different formats (table, list, json object, etc.?)
Copy linkTweet thisAlerts:
@DerokorianauthorMar 30.2011 — One more question:

In OOP and/or MCV is it still ok to have global functions (not part of a class)? things like my pagebar function (which takes query,pagesize, and current page and print out pagination) or sqlSafe (which replaces quotes and other unsavory characters to their html code equiv). I just dont see how to put those in an object...

Also thanks for all the advice its much appreciated. ?
Copy linkTweet thisAlerts:
@NogDogMar 30.2011 — If is always "okay" to do whatever works and best supports how you want to develop and maintain your application. Whether there are some OOP purists who will disagree with that or not, I don't know and don't really care much. ?

CodeIgniter, for example, comes with a bunch of "helper" functions that you load as needed -- and some that are loaded be default.
Copy linkTweet thisAlerts:
@DerokorianauthorMar 31.2011 — So Nog just want to give a big thank you, I think I get it... its just quite a bit different than procedural coding which is what I'm used to.
Copy linkTweet thisAlerts:
@NogDogMar 31.2011 — If I have not suggested it to you already in another thread, I found Matt Zandstra's book [i]PHP 5 Objects, Patterns, and Practice[/i] to be a big help for me to to get a grip on using object-oriented techniques with PHP. It is something that for most of us you just need to keep working at until you reach that "eureka" moment where things start to click and you really start to get it. ?
×

Success!

Help @Derokorian spread the word by sharing this article on Twitter...

Tweet This
Sign in
Forgot password?
Sign in with TwitchSign in with GithubCreate Account
about: ({
version: 0.1.9 BETA 5.6,
whats_new: community page,
up_next: more Davinci•003 tasks,
coming_soon: events calendar,
social: @webDeveloperHQ
});

legal: ({
terms: of use,
privacy: policy
});
changelog: (
version: 0.1.9,
notes: added community page

version: 0.1.8,
notes: added Davinci•003

version: 0.1.7,
notes: upvote answers to bounties

version: 0.1.6,
notes: article editor refresh
)...
recent_tips: (
tipper: @AriseFacilitySolutions09,
tipped: article
amount: 1000 SATS,

tipper: @Yussuf4331,
tipped: article
amount: 1000 SATS,

tipper: @darkwebsites540,
tipped: article
amount: 10 SATS,
)...