Я много читал о том, как и почему использовать подход MVC в приложении. Я видел и понимаю примеры модели, я видел и понимаю примеры View …., но я все еще неясен на контроллере. Мне бы очень хотелось увидеть достаточно подробный пример контроллера (ов). (в PHP, если это возможно, но любой язык поможет)
Спасибо.
PS: Было бы здорово, если бы я мог увидеть пример страницы index.php, которая решает, какой контроллер использовать и как.
EDIT: Я знаю, какая задача контроллера, я просто не понимаю, как это сделать в ООП.
Пример запроса
Поместите что-то вроде этого в index.php
:
<?php // Holds data like $baseUrl etc. include 'config.php'; $requestUrl = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']; $requestString = substr($requestUrl, strlen($baseUrl)); $urlParams = explode('/', $requestString); // TODO: Consider security (see comments) $controllerName = ucfirst(array_shift($urlParams)).'Controller'; $actionName = strtolower(array_shift($urlParams)).'Action'; // Here you should probably gather the rest as params // Call the action $controller = new $controllerName; $controller->$actionName();
На самом деле базовый, но вы понимаете … (Я также не заботился о загрузке класса контроллера, но я думаю, что это можно сделать либо с помощью автоматической загрузки, либо вы знаете, как это сделать.)
Пример простого контроллера (контроллеры / login.php):
<?php class LoginController { function loginAction() { $username = $this->request->get('username'); $password = $this->request->get('password'); $this->loadModel('users'); if ($this->users->validate($username, $password)) { $userData = $this->users->fetch($username); AuthStorage::save($username, $userData); $this->redirect('secret_area'); } else { $this->view->message = 'Invalid login'; $this->view->render('error'); } } function logoutAction() { if (AuthStorage::logged()) { AuthStorage::remove(); $this->redirect('index'); } else { $this->view->message = 'You are not logged in.'; $this->view->render('error'); } } }
Как вы видите, контроллер заботится о «потоке» приложения – так называемой прикладной логике. Он не заботится о хранении и представлении данных. Он скорее собирает все необходимые данные (в зависимости от текущего запроса) и присваивает его представлению …
Обратите внимание, что это не сработает ни с какой структурой, которую я знаю, но я уверен, что вы знаете, какие функции должны выполнять.
Вот хорошая статья Джо Стампа (бывший ведущий архитектор digg.com). Эта статья является частью серии по внедрению MVC в PHP. Ссылка
Представьте, что в пользовательском интерфейсе есть экраны, на которых пользователь вводит некоторые критерии поиска, экран, на котором отображается список резюме совпадающих записей, и экран, где после выбора записи он отображается для редактирования. Будет некоторая логика, связанная с первоначальным поиском на линиях
if search criteria are matched by no records redisplay criteria screen, with message saying "none found" else if search criteria are matched by exactly one record display edit screen with chosen record else (we have lots of records) display list screen with matching records
Куда должна идти эта логика? Не так ли в представлении или модели? Следовательно, это задача диспетчера. Контроллер также будет отвечать за принятие критериев и обращение к методу модели для поиска.
<?php class Router { protected $uri; protected $controller; protected $action; protected $params; protected $route; protected $method_prefix; /** * * @return mixed */ function getUri() { return $this->uri; } /** * * @return mixed */ function getController() { return $this->controller; } /** * * @return mixed */ function getAction() { return $this->action; } /** * * @return mixed */ function getParams() { return $this->params; } function getRoute() { return $this->route; } function getMethodPrefix() { return $this->method_prefix; } public function __construct($uri) { $this->uri = urldecode(trim($uri, "/")); //defaults $routes = Config::get("routes"); $this->route = Config::get("default_route"); $this->controller = Config::get("default_controller"); $this->action = Config::get("default_action"); $this->method_prefix= isset($routes[$this->route]) ? $routes[$this->route] : ''; //get uri params $uri_parts = explode("?", $this->uri); $path = $uri_parts[0]; $path_parts = explode("/", $path); if(count($path_parts)){ //get route if(in_array(strtolower(current($path_parts)), array_keys($routes))){ $this->route = strtolower(current($path_parts)); $this->method_prefix = isset($routes[$this->route]) ? $routes[$this->route] : ''; array_shift($path_parts); } //get controller if(current($path_parts)){ $this->controller = strtolower(current($path_parts)); array_shift($path_parts); } //get action if(current($path_parts)){ $this->action = strtolower(current($path_parts)); array_shift($path_parts); } //reset is for parameters //$this->params = $path_parts; //processing params from url to array $aParams = array(); if(current($path_parts)){ for($i=0; $i<count($path_parts); $i++){ $aParams[$path_parts[$i]] = isset($path_parts[$i+1]) ? $path_parts[$i+1] : null; $i++; } } $this->params = (object)$aParams; } } }
по<?php class Router { protected $uri; protected $controller; protected $action; protected $params; protected $route; protected $method_prefix; /** * * @return mixed */ function getUri() { return $this->uri; } /** * * @return mixed */ function getController() { return $this->controller; } /** * * @return mixed */ function getAction() { return $this->action; } /** * * @return mixed */ function getParams() { return $this->params; } function getRoute() { return $this->route; } function getMethodPrefix() { return $this->method_prefix; } public function __construct($uri) { $this->uri = urldecode(trim($uri, "/")); //defaults $routes = Config::get("routes"); $this->route = Config::get("default_route"); $this->controller = Config::get("default_controller"); $this->action = Config::get("default_action"); $this->method_prefix= isset($routes[$this->route]) ? $routes[$this->route] : ''; //get uri params $uri_parts = explode("?", $this->uri); $path = $uri_parts[0]; $path_parts = explode("/", $path); if(count($path_parts)){ //get route if(in_array(strtolower(current($path_parts)), array_keys($routes))){ $this->route = strtolower(current($path_parts)); $this->method_prefix = isset($routes[$this->route]) ? $routes[$this->route] : ''; array_shift($path_parts); } //get controller if(current($path_parts)){ $this->controller = strtolower(current($path_parts)); array_shift($path_parts); } //get action if(current($path_parts)){ $this->action = strtolower(current($path_parts)); array_shift($path_parts); } //reset is for parameters //$this->params = $path_parts; //processing params from url to array $aParams = array(); if(current($path_parts)){ for($i=0; $i<count($path_parts); $i++){ $aParams[$path_parts[$i]] = isset($path_parts[$i+1]) ? $path_parts[$i+1] : null; $i++; } } $this->params = (object)$aParams; } } }
<?php class App { protected static $router; public static function getRouter() { return self::$router; } public static function run($uri) { self::$router = new Router($uri); //get controller class $controller_class = ucfirst(self::$router->getController()) . 'Controller'; //get method $controller_method = strtolower((self::$router->getMethodPrefix() != "" ? self::$router->getMethodPrefix() . '_' : '') . self::$router->getAction()); if(method_exists($controller_class, $controller_method)){ $controller_obj = new $controller_class(); $view_path = $controller_obj->$controller_method(); $view_obj = new View($controller_obj->getData(), $view_path); $content = $view_obj->render(); }else{ throw new Exception("Called method does not exists!"); } //layout $route_path = self::getRouter()->getRoute(); $layout = ROOT . '/views/layout/' . $route_path . '.phtml'; $layout_view_obj = new View(compact('content'), $layout); echo $layout_view_obj->render(); } public static function redirect($uri){ print("<script>window.location.href='{$uri}'</script>"); exit(); } }
Проверьте это:
<?php global $conn; require_once("../config/database.php"); require_once("../config/model.php"); $conn= new Db; $event = isset($_GET['event']) ? $_GET['event'] : ''; if ($event == 'save') { if($conn->insert("employee", $_POST)){ $data = array( 'success' => true, 'message' => 'Saving Successful!', ); } echo json_encode($data); } if ($event == 'update') { if($conn->update("employee", $_POST, "id=" . $_POST['id'])){ $data = array( 'success' => true, 'message' => 'Update Successful!', ); } echo json_encode($data); } if ($event == 'delete') { if($conn->delete("employee", "id=" . $_POST['id'])){ $data = array( 'success' => true, 'message' => 'Delete Successful!', ); } echo json_encode($data); } if ($event == 'edit') { $data = $conn->get("select * from employee where id={$_POST['id']};")[0]; echo json_encode($data); } ?>