proszę o krytykę, mam wrażenie, że trochę błądzę w założeniach MVC i chcę mieć pewność w których miejscach
proszę tylko nie do końca zwracać uwagę na "niefortunnie" dobrane nazwy klas i funkcji, wiem, że wymaga to staranniejszej organizacji, na razie jest tak, by __autoload łapał wszystkie potrzebne mi klasy
o dziwo potworek ten działa tak jak zakładałem .htacces przekierowuje wszystko na index.php a linki buduję np. tak www.mojastrona.pl/product/viewproduct/25
index.php - załącza ini.php, tworzy router, tworzy dispatcher, przekazuje router do dispatchera
<?php include ('core/ini.php'); $router=router::getInstance(); $dispatcher=dispatcher::getInstance(); $dispatcher->start($router); ?>
ini.php - ustala ścieżki i załącza funkcję __autoload
<?php function __autoload($object){ require_once("c{$object}.php"); } ?>
cConfigs.php - udostępnia dane
<?php class configs{ const ALLOWED_URL_CHARS="/[^A-z0-9\/\^]/"; const DEFAULT_CONTROLLER="products"; const DEAFAULT_ACTION="index"; const DB_USER="test"; const DB_PASSWORD="*******"; const PATH_CORE="core"; const PATH_CONTROLLERS="app/controllers"; const PATH_VIEWS="app/views"; const ERROR_NO_PAGE="errornopage"; { return self::$ALLOWED_CONTROLLERS; } } ?>
cRouter.php - obsługa adresu wywołania (dzieli url na parametry)
<?php class router { private $url; private $routeParts; private $controller; private $action; private $parametry; private function __construct() { $this->executeRouting(); } { if(self::$instance==false){ self::$instance= new router(); } return self::$instance; } private function executeRouting() { $patern=configs::ALLOWED_URL_CHARS; $url=$this->url; { $route=$url['0']; { $this->controller=$routeParts['0']; { $this->action=$routeParts['1']; $routePartsParam=$routeParts; $this->parametry=$routePartsParam; }else{ $this->parametry=false; } }else{ $this->action=false; $this->parametry=false; } }else{ $this->controller=false; $this->action=false; $this->parametry=false; } } } public function getController() { return $this->controller; } public function getAction() { return $this->action; } public function getParametry() { return $this->parametry; } } ?>
cDispatcher.php - pobiera dane z routera i przetwarza je (sprawdza czy są poprawne i dozwolone, zwraca wartości domyślne - inicjuje właściwe kontrolery i akcje)
<?php class dispatcher { private $controller; private $action; private $parametry; { if(self::$instance==false){ self::$instance= new dispatcher(); } return self::$instance; } public function start($router) { $controller=$router->getController(); $action=$router->getAction(); $parametry=$router->getParametry(); self::setParams($controller,$action,$parametry); self::dispatch(); } private function setParams($controller,$action,$parametry) { //POPRAWNY KONTROLER i AKCJA if($controller!=false && in_array($controller,configs::getAllowed_Controllers())&& $action!=false && method_exists($controller, $action)) { $this->controller=$controller; $this->action=$action; { $this->parametry=$parametry; } else{ $this->parametry=false; } } //NIEPOPRAWNY KONTROLER LUB POPRAWNY KONTROLER I NIEPOPRAWNA AKCJA elseif(($controller!=false && !in_array($controller,configs::getAllowed_Controllers()))||($action!=false && !method_exists($controller, $action))) { $this->controller=configs::ERROR_NO_PAGE; $this->action=configs::DEAFAULT_ACTION; $this->parametry=false; } //BRAK KONTROLERA LUB POPRAWNY KONTROLER I BRAK AKCJI elseif(($controller==false)||($controller!=false && in_array($controller,configs::getAllowed_Controllers())&& $action==false)) { $this->controller=configs::DEFAULT_CONTROLLER; $this->action=configs::DEAFAULT_ACTION; $this->parametry=false; } } private function dispatch() { $controller=$this->controller; $action=$this->action; $parametry=$this->parametry; $app = new $controller(); if($parametry!=false){ $app->setParametry($parametry); } $app->$action(); } } ?>
cController.php - kontroler rodzic, ustawia parametry dla akcji, sprawdza ich ilość, ustawia model i widok
abstract class controller implements interfaceBasic { protected $parametry; protected $view; protected $model; protected $viewname; public function setParametry($parametry) { $this->parametry=$parametry; } public function countParametry($parametry, $parNum) { { $controller=configs::ERROR_NO_PAGE; $action=configs::DEAFAULT_ACTION; $app= new $controller; $app->$action(); return $error=true; } } protected function setModel() { $model= new model(); $this->model=$model; } protected function setView($viewname) { $widokname="view".$viewname; $widok=new $widokname(); $this->widok=$widok; } } ?>
cInterfaceBasic.php - żąda funkcji index() która jest domyślną dla wszystkich kontrolerów
<?php interface interfaceBasic { function index(); function countParametry($parametry, $parNum); }
cProducts.php- kontroler produktów - domyślny kontroler - wywołuje akcję index() która listuje wszystkie produkty lub akcję viewproduct pokazującą pojedyńczy produkt po parametrze $id produktu
<?php class products extends controller { public $use_layout=false; public function __construct() { parent::setModel(); } public function index() { parent::setView("products"); $model=$this->model; $widok=$this->widok; $widok->setModelInView($model); $widok->render(); } public function viewproduct() { parent::setView(__FUNCTION__); $parametry=$this->parametry; $parNum=1; $error=self::countParametry($parametry,$parNum); if($error!=true) { $model=$this->model; $widok=$this->widok; $widok->setModelInView($model); $widok->setParamsInView($parametry); $widok->render(); } } } ?>
cErrornopage.php - klasa błędu - tylko na potrzeby zaznaczenia momentu błedu
<?php class errornopage extends controller implements interfaceBasic { function index() { } function __construct() { } } ?>
cDB.php - baza danych
<?php abstract class DB { { self::$user=configs::DB_USER; self::$password=configs::DB_PASSWORD; } { self::setParams(); $user=self::$user; $password=self::$password; $mysql=self::$mysql; self::$pdo=new PDO($mysql,$user,$password); } } ?>
cModel.php - model
<?php class model extends DB { private $result; public function __construct() { parent::setConnection(); } public function getAllProducts() { $pdo=self::$pdo; $query=$pdo->query('SELECT * FROM products '); $this->result=$query; } public function getProduct($id) { $pdo=self::$pdo; $this->result=$query; } public function getResult() { return $this->result; } } ?>
cView.php - klasa widok - rodzic
<?php abstract class view { protected $model; protected $parametry; public function setModelInView($model) { $this->model=$model; } public function setParamsInView($parametry){ $this->parametry=$parametry; } } ?>
CViewProducts.php - widok dla listy produktów
<?php class viewproducts extends view { public function render() { $model=$this->model; $model->getAllProducts(); $result=$model->getResult(); while($row=$result->fetch()) { echo '<hr/> <p><b>iD:</b> '.$row['PRODUCTID'].'</p> <p><b>Nazwa:</b> <a href="products/viewproduct/'.$row['PRODUCTID'].'">'.$row['PRODUCTNAME'].'</a></p> <p><b>Cena:</b> '.$row['UNITPRICE'].'</p> <p><b>Na Magazynie:</b> '.$row['UNITSINSTOCK'].'</p>'; } } } ?>
cViewViewproducts.php - widok dla pojedynczego produktu
<?php class viewviewproduct extends view { public function render() { $parametry=$this->parametry; $model=$this->model; $model->getProduct($parametry['0']); $result=$model->getResult(); $row=$result->fetch(); echo '<hr/> <p><b>iD:</b> '.$row['PRODUCTID'].'</p> <p><b>Nazwa:</b> '.$row['PRODUCTNAME'].'</p> <p><b>Cena:</b> '.$row['UNITPRICE'].'</p> <p><b>Na Magazynie:</b> '.$row['UNITSINSTOCK'].'</p>'; } } ?>
baza danych zapożyczona z innego przykładu
CREATE TABLE products ( PRODUCTID int(11) NOT NULL AUTO_INCREMENT, PRODUCTNAME varchar(255) NOT NULL DEFAULT '', UNITPRICE varchar(255) NOT NULL DEFAULT '', UNITSINSTOCK varchar(255) NOT NULL DEFAULT '', DISCONTINUED varchar(255) NOT NULL DEFAULT '', PRIMARY KEY (PRODUCTID) ) TYPE=MyISAM; # # Dumping data for table `products` # INSERT INTO products VALUES (1, 'Chai', '18', '39', '0'); INSERT INTO products VALUES (2, 'Chang', '19', '17', '0'); INSERT INTO products VALUES (3, 'Aniseed Syrup', '10', '13', '0'); INSERT INTO products VALUES (4, 'Chef Antons Cajun Seasoning', '22', '53', '0'); INSERT INTO products VALUES (5, 'Chef Anton Gumbo Mix', '21.35', '0', '1'); INSERT INTO products VALUES (6, 'Grandma Boysenberry Spread', '25', '120', '0'); INSERT INTO products VALUES (7, 'Uncle Bob Organic Dried Pears', '30', '15', '0'); INSERT INTO products VALUES (8, 'Northwoods Cranberry Sauce', '40', '6', '0'); INSERT INTO products VALUES (9, 'Mishi Kobe Niku', '97', '29', '1'); INSERT INTO products VALUES (10, 'Ikura', '31', '31', '0'); INSERT INTO products VALUES (11, 'Queso Cabrales', '21', '22', '0'); INSERT INTO products VALUES (12, 'Queso Manchego La Pastora', '38', '86', '0'); INSERT INTO products VALUES (13, 'Konbu', '6', '24', '0'); INSERT INTO products VALUES (14, 'Tofu', '23.25', '35', '0'); INSERT INTO products VALUES (15, 'Genen Shouyu', '15.5', '39', '0');