I've tried two times before but had to stop due to lack of planning.
Lately I've been reading about MVC (Model-View-Controller) designs and registry patterns.
I've come up with a solution that I think might work.
I have a registry class to store all objects and a module handler which fetches output from the different modules (like a router).
But in this example you can load several modules simultaneously. That means you can assign module-output anywhere on the page (as main content, block content, etc).
The 'main module' (requested by user, think $_GET['mod']) will always be responsible for the main content (the body of the page). But every other module can also be loaded and create output for other parts of the page (like a poll in a block).
My approach is best explained by looking at a simplified framework I wrote.
Code: Select all
<?php
function __autoload($class_name)
{
require_once($class_name . '.php');
}
class Registry
{
// Registry to hold all objects
private static $instance;
private $vars = array();
public static function getInstance()
{
if (!isset(self::$instance))
{
echo "Creating instance of registry<br />";
$c = __CLASS__;
self::$instance = new $c;
}
else
{
echo "Registry instance already exists.<br />";
}
return self::$instance;
}
public function __set($key, $var)
{
echo "set $key to registry class<br />";
if (!isset($this->vars[$key]))
{
$this->vars[$key] = $var;
}
return true;
}
public function __get($key)
{
echo "get $key<br />";
if (!isset($this->vars[$key]))
{
return null;
}
return $this->vars[$key];
}
public function __unset($var)
{
echo "<br />unset";
unset($this->vars[$key]);
}
}
class Database
{
// Database class. Nothing here yet
function __construct()
{
echo "Constructing DB<br />";
}
public function query($sql)
{
echo $sql . "<br />";
}
}
class Template
{
// Class to handle views. Includes set/get and output functions
private $partials = array();
function set($key, $var)
{
$this->partials[$key] = $var;
}
}
class Modhandler
{
// Register modules we want to use.
// Use modules to assign content
private $registry; // registry obj
// main mod (requested by user)
private $mainmod = '';
// Holds module info, eventually fetched from database.
private $modules = array();
// Holds the object of each module class
private $modObjects = array();
function __construct($mainmod)
{
$this->registry = Registry::getInstance();
$this->mainmod = $mainmod; // mainmod is the module requested by user. E.g. index.php?mainmod=articles
}
function delegate()
{
// Load $mainmod and let it assign some content.
// If $mainmod lets us (maybe it wants to print and article and doesn't want header/footer?),
// we assign some content from other modules
$mainmod = $this->mainmod;
$this->loadModule($mainmod);
$this->registry->template->set('content', $this->execute($mainmod)); // $mainmod decides our main content
// Check if $mainmod let's is assign other stuff to the template (not added yet)
// $mainmod also determines the title of the page.
// What else do we want on our site? Maybe put some links in a block?
// Then load the 'links' module.
$this->loadModule('links');
$this->registry->template->set('leftblock', $this->execute('links', 'viewcat', 6));
}
function loadModule($mod)
{
// Load a module's class
echo "loaded module $mod <br/>";
include('./modules/' . $mod . '/index.php');
$this->modObjects[$mod] = new $mod;
}
function execute($mod, $action='index', $params=array())
{
// return output from requested module.
return call_user_func_array(array($this->modObjects[$mod], $action), array($params));
}
}
abstract class Module
{
// Abstract class for all modules to inherit.
// $mainmod (the module requested by user ($_GET['mod']) sets the config variables to whatever it wants
abstract protected function index();
private $config = array(
'pagetitle' => '',
'showheader' => true
);
}
// Let's start
$db = new Database;
$modhandler = new Modhandler($_GET['mainmod']);
$template = new Template;
$registry = Registry::getInstance();
// Register objects to registry. Am I doing this correctly?
$registry->template = $template;
$registry->db = $db;
$registry->mod = $modhandler;
$modhandler->delegate();
echo "<br /><br />" . str_replace(' ', ' ', nl2br(print_r($GLOBALS, true)));
?>Also, if anyone has something to say about the object oriented programming in this example, that would be great. I'm still learning, and it would be nice to know if I've grasped the basics, e.g. how the registry object should be treated.
Thanks in advance.