Before to work with Zend Framework, I used to do something similar.
Here is the files/folders structure :
/
/views
/layouts
/controllers
/library
/etc
/data
Site.php
index.php
Views : contains all the templates, one per controller/action
Layouts : a layout which get a var containing the filename to include (from the views)
controllers : the controllers
library : all extra tools needed for the project
etc : documentations, etc..
data : for file upload
Site.php file used to init the whole project, kind of a bootstrap called by the index.php
index.php : call the bootstrap
<?php
class Site
{
protected $_action = NULL;
protected $_contentFile = NULL;
protected $_args = array();
protected $_headTitle = NULL;
protected $_headerStack = array();
public function __construct ($action)
{
$this->setAction($action);
$this->setArgs();
}
public function setHeader($name = null, $value = null)
{
if (null != $name && null != $value)
{
$this->_headerStack[$name] = $value;
}
}
public function sendHeaders()
{
if (null != $this->_headerStack)
{
foreach ($this->_headerStack as $key => $value)
{
header($key . ':' . ' ' . $value);
}
}
return $this;
}
public function setAction($action)
{
$this->_action = (! empty($action) ) ? $action : 'error';
return $this;
}
public function setArgs()
{
$this->_args['GET'] = $_GET;
$this->_args['POST'] = $_POST;
}
public function getParam($name)
{
if ( ! empty($this->_args['GET'][$name]))
{
return $this->_args['GET'][$name];
} else {
return null;
}
}
public function getParams()
{
return $this->_args['GET'];
}
public function getPost()
{
return $this->_args['POST'];
}
public function preRun()
{
if (is_file('views/' . $this->_action . '.phtml'))
{
$content = 'views/' . $this->_action . '.phtml';
$this->setContentFile($content);
}
if (is_file('library/' . ucfirst($this->_action) . 'Action.php'))
{
require_once 'library/' . ucfirst($this->_action) . 'Action.php';
if (function_exists ('init'))
{
init();
}
}
}
public function run()
{
$this->sendHeaders();
$this->preRun();
require_once 'layouts/main.phtml';
$this->sendHeaders();
}
public function setContentFile($content)
{
$this->_contentFile = ( !empty($content) ) ? $content : '';
return $this;
}
public function getContent()
{
require_once $this->_contentFile;
}
public function setHeadTitle($title)
{
$this->_headTitle = $title;
return $this;
}
public function getHeadTitle()
{
return $this->_headTitle;
}
}
Then, in my index I did :
$action = $_GET['action'];
$site = new Site($action);
$site->run();
I removed some extra security checks for convenience...
You can then extends this to include a models directory called from the controller, etc...