Skip to content

Instantly share code, notes, and snippets.

@millken
Created September 1, 2010 06:35
Show Gist options
  • Save millken/560318 to your computer and use it in GitHub Desktop.
Save millken/560318 to your computer and use it in GitHub Desktop.
<?php
/*
*a small MVC framework written by millken@gmail.com
*last modifed 2010-8-31 17:43
*/
if(!defined('__controller_path__'))
define('__controller_path__', dirname(__FILE__) . '/controller/');
if(!defined('__model_path__'))
define('__model_path__', dirname(__FILE__) . '/model/');
if(!defined('__config_path__'))
define('__config_path__', dirname(__FILE__) . '/config/');
class mkMVC{
/* config file values */
var $config = null;
/* controller object */
var $controller = null;
/* controller method name */
var $action = null;
/* server path_info */
var $path_info = null;
/* array of url path_info segments */
var $url_segments = null;
private $routes = null;
private $segments = null;
public function __construct($id='default') {
/* set instance */
set_exception_handler(array('mkMVC', 'exception_handler'));
self::instance($this,$id);
}
public static function &instance($new_instance=null,$id='default') {
static $instance = array();
if(isset($new_instance) && is_object($new_instance))
$instance[$id] = $new_instance;
return $instance[$id];
}
public function setupRouting() {
@include(__config_path__.'router.php');
$this->routes = ( ! isset($route) OR ! is_array($route)) ? array() : $route;
unset($route);
$this->path_info = !empty($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : '';
$this->url_segments = !empty($this->path_info) ? array_filter(explode('/',$this->path_info)) : null;
$uri = @implode('/',$this->url_segments);
// Loop through the route array looking for wild-cards
foreach ((array)$this->routes as $key => $val) {
// Convert wild-cards to RegEx
$key = str_replace(':any', '.+', str_replace(':num', '[0-9]+', $key));
// Does the RegEx match?
if (preg_match('#^'.$key.'$#', $uri)) {
// Do we have a back-reference?
if (strpos($val[2], '$') !== FALSE AND strpos($key, '(') !== FALSE) {
//get parameter
$val[2] = preg_replace('#^'.$key.'$#', $val[2], $uri);
}
$this->segments = $val;
return;
}
}
$this->segments = array('home','index');
}
public function setupController($registry=null) {
$controller_file = __controller_path__ . $this->segments[0] . ".php";
if(!file_exists($controller_file))
throw new Exception("Unknown file: '$controller_file'");
include($controller_file);
$controller_name = preg_replace('!\W!','',$this->segments[0]);
/* see if controller class exists */
$controller_class = $controller_name.'_Controller';
/* instantiate the controller */
if(!class_exists($controller_class,false))
throw new Exception("class not exists: '$controller_class'");
$this->controller = new $controller_class($registry);
$this->action = $this->segments[1];
}
public function disPatch($registry=null) {
/* url remapping/routing */
$this->setupRouting();
if(is_null($registry))$registry = new Registry();
@parse_str($this->segments[2], $params);
foreach((array)$params as $key=>$val)$registry->set($key,$val);
/* create controller object and get controller method */
$this->setupController($registry);
$this->controller->{$this->action}();
}
public function exception_handler(Exception $e) {
printf("<pre style=\"text-align: left; background-color: #fcc; border: 1px solid #600; color: #600; display: block; margin: 1em 0; padding: .33em 6px\">%s(%d): %s (%d) [%s]\n%s\n</pre>", $e->getFile(), $e->getLine(), $e->getMessage(), $e->getCode(), get_class($e), $e->getTraceAsString());
}
}
abstract class Controller{
protected $registry;
function __construct($registry=null){
/* save controller instance */
mkMVC::instance($this,'controller');
$this->registry = $registry;
$this->load = new Load($registry);
}
public function __get($key) {
return $this->registry->get($key);
}
public function __set($key, $value) {
$this->registry->set($key, $value);
}
public function __call($function, $args) {
throw new Exception("Unknown controller method '{$function}'");
}
}
abstract class Model{
protected $registry;
public function __construct($registry=null) {
$this->registry = $registry;
}
public function __get($key) {
return $this->registry->get($key);
}
public function __set($key, $value) {
$this->registry->set($key, $value);
}
}
class Registry {
private $data = array();
public function set($key, $value) {
return $this->__set($key, $value);
}
public function get($key) {
return $this->__get($key);
}
public function __get($key) {
return (isset($this->data[$key]) ? $this->data[$key] : NULL);
}
public function __set($key, $value) {
if(!empty($key) && !isset($this->data[$key])) $this->data[$key] = $value;
return $this;
}
public function __isset($key) {
return isset($this->data[$key]);
}
public function __unset($key) {
if(isset($this->data[$key]))unset($this->data[$key]);
}
}
class Load{
protected $registry;
function __construct($registry=null) {
$this->registry = $registry;
}
public function model($model_name,$model_alias=null)
{
/* if no alias, use the model name */
if(!isset($model_alias))
$model_alias = $model_name;
if(empty($model_alias))
throw new Exception("Model name cannot be empty");
$filename = __model_path__ . $model_name . '.php';
include($filename);
$model_name = preg_replace('!\W!','',$model_name) . '_Model';
if(method_exists($this,$model_alias))
throw new Exception("Model name '{$model_alias}' is an invalid (reserved) name");
/* model already loaded? silently skip */
if(isset($this->$model_alias))
return true;
/* get instance of controller object */
$controller = mkMVC::instance(null,'controller');
/* instantiate the object as a property */
$controller->$model_alias = new $model_name($this->registry);
return true;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment