Пример контроллера MVC

Я много читал о том, как и почему использовать подход 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; } } } 
  1. Создание структуры папок
  2. Настройка .htaccess и виртуальные хосты
  3. Создать конфигурационный класс для создания конфигурационного массива

контроллер

  1. Создать класс маршрутизатора с защищенным нестационарным, с геттерами
  2. Создайте init.php с конфигурацией include & autoload и включите пути (lib, controlelrs, models)
  3. Создайте файл конфигурации с маршрутами, значениями по умолчанию (маршрут, контроллеры, действие)
  4. Установка значений в маршрутизаторе – по умолчанию
  5. Задайте пути uri, взорвите uri и задайте маршрут, контроллер, действие, параметры, параметры процесса.
  6. Создайте класс приложения для запуска приложения путем передачи uri – (защищенный маршрутизатор obj, run func)
  7. Создайте родительский класс контроллера, чтобы наследовать все остальные контроллеры (защищенные данные, модель, параметры – не статические), данные набора, параметры в конструкторе.
  8. Создайте контроллер и расширьте его выше родительского класса и добавьте метод по умолчанию.
  9. Вызовите класс и метод контроллера в функции запуска. метод должен иметь префикс.
  10. Вызовите метод, если exisist

Просмотры

  1. Создайте класс родительского представления для создания представлений. (данные, путь) с пулом по умолчанию, установить контроллер, выполнять функции для возврата полного пути tempalte (не статические)
  2. Создайте функцию рендеринга с ob_start (), ob_get_clean, чтобы вернуть и отправить содержимое в браузер.
  3. Измените класс приложения для анализа данных для просмотра класса. если путь возвращен, перейдите также к классу просмотра.
  4. Макеты … это зависит от маршрутизатора. пересмотреть макет html для просмотра и рендеринга
 <?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); } ?>