W celu lepszego zrozumienia idei MVC postanowiłem troszkę się pobawić i korzystając z wielu dostępnych mi źródeł napisać coś na wzór pseudo-MVC-frameworka. Mam jednak parę pytań, z czego najważniejsze to czy to się w ogóle trzyma kupy?
Autoloader wygląda następująco:
Mam taki pseudo "front Controller", który ma za zadanie odpalenie odpowiedniego kontrolera na podstawie $_SERVER['request'] i wygląda on tak:
<?php function __autoload($className) { if(file_exists(ROOT.DIRECTORY_SEPARATOR.'library'.DIRECTORY_SEPARATOR.strtolower($className).'.class.php')) { require_once ROOT.DIRECTORY_SEPARATOR.'library'.DIRECTORY_SEPARATOR.strtolower($className).'.class.php'; } elseif(file_exists(ROOT.DIRECTORY_SEPARATOR.'application'.DIRECTORY_SEPARATOR.'controllers'.DIRECTORY_SEPARATOR.strtolower($className).'.php')) { require_once ROOT.DIRECTORY_SEPARATOR.'application'.DIRECTORY_SEPARATOR.'controllers'.DIRECTORY_SEPARATOR.strtolower($className).'.php'; } elseif(file_exists(ROOT.DIRECTORY_SEPARATOR.'application'.DIRECTORY_SEPARATOR.'models'.DIRECTORY_SEPARATOR.strtolower($className).'.php')) { require_once ROOT.DIRECTORY_SEPARATOR.'application'.DIRECTORY_SEPARATOR.'models'.DIRECTORY_SEPARATOR.strtolower($className).'.php'; } elseif(file_exists(ROOT.DIRECTORY_SEPARATOR.'library'.DIRECTORY_SEPARATOR.'helpers'.DIRECTORY_SEPARATOR.strtolower($className).'.class.php')) { require_once ROOT.DIRECTORY_SEPARATOR.'library'.DIRECTORY_SEPARATOR.'helpers'.DIRECTORY_SEPARATOR.strtolower($className).'.class.php'; } else { // nie ma takiego pliku, jakis error handler? } }
Klasa Controller, po której dziedziczy każdy kontroler wygląda natomiast tak
<?php class FrontController { private $_queryString; private $_controller; private $_action; private $_dispatch; public function callHook($url) { $controller = $urlArray[0]?$urlArray[0]:'main'; $action = $urlArray[0]?$urlArray[0]:'index'; $queryString = $urlArray; $controllerName = $controller; $model = $controller; $controller .= 'Controller'; $this->_queryString = $queryString; $this->_controller = $controller; $this->_action = $action; if(class_exists($controller)) { $this->_dispatch = new $controller($model, $controllerName, $action); } else { $this->_action = 'error404'; $this->_controller = 'error'; $this->_queryString = $_SERVER; $this->_dispatch = new ErrorController('error', 'error', 'error404'); } } public function addHelper($class) { if($class instanceof TemplateHelper) { $this->_dispatch->addTemplateHelper($class); } else { $this->_dispatch->addModule($class); } } public function run() { if((int)method_exists($this->_controller, 'init')) { $this->_dispatch->init(); } $this->_dispatch->{$this->_action}($this->_queryString); $this->_dispatch->render(); } }
A klasa Template, która odpowiada za wczytanie i wyrenderowanie odpowiedniej templatki (jest dość primitywna)
class Controller { protected $_model; protected $_controller; protected $_action; protected $_template; protected $_modules; public function __construct($model, $controller, $action) { $this->_controller = $controller; $this->_model = $model; $this->_action = $action; $this->_template = new Template($this->_controller, $this->_action); } public function addModule($module) { $this->_modules[get_class($module)] = $module; } public function addTemplateHelper($helper) { $this->_template->addTemplateHelper($helper); } public function set($name, $value) { $this->_template->set($name, $value); } public function render() { $this->_template->render(); } }
<?php class Template { protected $_controller; protected $_action; protected $_helpers; public function __construct($controller, $action) { $this->_controller = $controller; $this->_action = $action; } public function __set($name, $value) { $this->set($name, $value); } public function set($name, $value) { $this->_variables[$name] = $value; } public function addTemplateHelper($helper) { $this->_helpers[get_class($helper)] = $helper; } public function getHelper($helper) { return $this->_helpers[$helper]; } public function load($helper) { $template = new Template('helpers', $helper); $template->render(); } public function render($doNotRenderHeader = false) { if($doNotRenderHeader == false) { if(file_exists(ROOT.DIRECTORY_SEPARATOR.'application'.DIRECTORY_SEPARATOR.'views'.DIRECTORY_SEPARATOR.$this->_controller.DIRECTORY_SEPARATOR.'header.phtml')) { require_once ROOT.DIRECTORY_SEPARATOR.'application'.DIRECTORY_SEPARATOR.'views'.DIRECTORY_SEPARATOR.$this->_controller.DIRECTORY_SEPARATOR.'header.phtml'; } elseif(file_exists(ROOT.DIRECTORY_SEPARATOR.'application'.DIRECTORY_SEPARATOR.'views'.DIRECTORY_SEPARATOR.'header.phtml')) { require_once ROOT.DIRECTORY_SEPARATOR.'application'.DIRECTORY_SEPARATOR.'views'.DIRECTORY_SEPARATOR.'header.phtml'; } } require_once ROOT.DIRECTORY_SEPARATOR.'application'.DIRECTORY_SEPARATOR.'views'.DIRECTORY_SEPARATOR.$this->_controller.DIRECTORY_SEPARATOR.$this->_action.'.phtml'; if($doNotRenderHeader) { if(file_exists(ROOT.DIRECTORY_SEPARATOR.'application'.DIRECTORY_SEPARATOR.'views'.DIRECTORY_SEPARATOR.$this->_controller.DIRECTORY_SEPARATOR.'footer.phtml')) { require_once ROOT.DIRECTORY_SEPARATOR.'application'.DIRECTORY_SEPARATOR.'views'.DIRECTORY_SEPARATOR.$this->_controller.DIRECTORY_SEPARATOR.'footer.phtml'; } elseif(file_exists(ROOT.DIRECTORY_SEPARATOR.'application'.DIRECTORY_SEPARATOR.'views'.DIRECTORY_SEPARATOR.'footer.phtml')) { require_once ROOT.DIRECTORY_SEPARATOR.'application'.DIRECTORY_SEPARATOR.'views'.DIRECTORY_SEPARATOR.'footer.phtml'; } } } }
Jeśli komukolwiek udało się przebrnąć przez te linijki kodu mam 3 pytania:
a) Czy udało mi się uchwycić ideę OOP

c) Co mogę poprawić, żeby kod był bardziej OOP/MVC.
Przepraszam za chaotyczność (?) tego postu ale mam grypę i logiczne myślenie jest ciężkawe :<.
Pozdrawiam i z góry dzięki,
Vielta