Основной паттерн для создания фреймворков и других web-приложений. Фреймворки в PHP зачастую используют для больших проектов. Основное преимущество - это, конечно же, предоставление возможности строить проект при помощи паттерна MVC (Model-View-Controller).
Плюсы:
• вложенность шаблонов
• независимость представления от контроллера
• целостность шаблона
• возможность кэширования
• видимость переменных
• лаконичность кода
Расшифруем само понятие MVC:
Model - модели данных, которые многие и без того используют без фреймфорков. Фактически обычные классы для работы с разными данными.
View - представления. Это шаблонизатор, например, SMARTY либо собственный. Представления - это вид, в котором отображаются данные.
Controller – основной вызываемый класс, содержащий базовую логику приложения.
Рисунок 4.1 – Модели
Для понимания модели HMVC необходимо также иметь представление о роутинге (или маршрутизации) запросов. Главное отличие от MVC-паттерна - возможность передачи запроса по контроллерам.
По такому принципу построены почти все современные web-фреймворки (за исключением клиентских, таких как Angular, Backbone и др.)
В HMVC фактически процесс не меняется, т.к. последовательность действий в случае использования фреймворка остается той же, что и без него (принимаем данные - обрабатываем их в модели - выводим результат через представление).
HMVC позволяет легко соби рать воедино и легко управлять большими частями кода. А фреймворк вносит существенную долю автоматизации и простоты управления. Фреймворк - это склад различных классов и библиотек, которые позволяют отказаться от изобретения велосипедов и начать использовать готовые решения, тем самым увеличив скорость разработки. Любой разработчик, если он занимается профессиональной разработкой, со временем приходит к созданию собственной библиотеке классов, основанной, как правило, на уже готовых классах.
Современные фрэймворки не только предлагают для использования готовые классы, но и свою структуру папок.
У каждого из фрэймворков есть свои преимущества и свои недостатки.
3.1 HMVC
По концепции MVC, когда мы делаем запрос, мы, сперва, попадаем в контроллер (Controller). Затем в контроллере может происходить вызов модели (Model) (т.е. получение данных из модели),а затем передача этих данных в шаблон представления (View). Все очень просто, но это не всегда бывает удобно, хотя бы потому, что часто приходится вносить изменения в контроллеры либо дублировать контроллеры из-за того, что в них вносятся незначительные изменения. В связи с этим придумали концепцию HMVC, т.е. иерархическая MVC. По данной концепции мы также сперва делаем запрос к контроллеру, который в свою очередь может передать запрос к другому контроллеру. Взаимосвязь самого контроллера с моделью и шаблоном представления осталась той же. Концепцию HMVC помогают понять следующие технологии:
Маршрутизация
Запрос из адресной строки попадает в так называемый обработчик маршрутов, или маршрутизатор, или роутер (routes). Маршрутизатор определяет, какой контроллер необходимо вызывать.
Маршруты описываем в routes.php, указывая какой контролер и какой экшин будет отвечать за формирование той или иной страницы.
Route.php |
namespace application\core; use application\core\View; class Router { protected $routes = []; protected $params = []; public function __construct() { $arr = require 'application/config/routes.php'; foreach ($arr as $key => $val) { $this->add($key, $val); } } public function add($route, $params) { $route = preg_replace('/{([a-z]+):([^\}]+)}/', '(?P<\1>\2)', $route); $route = '#^'.$route.'$#'; $this->routes[$route] = $params; } public function match() { $url = trim($_SERVER['REQUEST_URI'], '/'); foreach ($this->routes as $route => $params) { if (preg_match($route, $url, $matches)) { foreach ($matches as $key => $match) { if (is_string($key)) { if (is_numeric($match)) { $match = (int) $match; } $params[$key] = $match; } } $this->params = $params; return true; } } return false; } public function run(){ if ($this->match()) { $path='application\controllers\\'.ucfirst($this-params['controller']).'Controller'; if (class_exists($path)) { $action = $this->params['action'].'Action'; if (method_exists($path, $action)) { $controller = new $path($this->params); $controller->$action(); } else { View::errorCode(404); } } else { View::errorCode(404); } } else { View::errorCode(404); } }
} |
Контроллеры
Контроллеры хранятся в папке core/controller/. Все контроллеры должны наследовать класс Controller. Этот класс также может хранится в папке core/controller, и в него можно поместить общую логику для других контроллеров. MainController расширяет базовый класс Controller.
Есть несколько способов определения маршрута для контроллера.
В файле config/routes.php.
А вот так будет выглядеть сам контроллер:
namespace application\controllers;
use application\core\Controller;
class MainController extends Controller {
echo ‘OK’;
}
Применение контроллеров в данной курсовой работе, контроллер для главной страницы
MainController.php |
namespace application\controllers; use application\core\Controller; use application\models\Admin; class MainController extends Controller { public function indexAction() {
$this->view->render('Главная страница'); } public function aboutAction() { $this->view->render('Обо мне'); } public function lovestoryAction() { $this->view->renderfoto('Любовная история '); } public function peddingAction() { $this->view->renderfoto('В ожидании'); } public function familyAction() { $this->view->renderfoto('Семнйное'); } public function eventsAction() { $this->view->renderfoto('Мероприятие'); } public function artdressAction() { $this->view->renderfoto('АРТ'); } public function carAction() { $this->view->renderfoto('Автомероприятие'); } public function weddingAction() { $this->view->renderfoto('Свадьба'); } public function portretAction() { $this->view->renderfoto('Портрет'); } public function contactAction() { if (!empty($_POST)) { if (!$this->model->contactValidate($_POST)) { $this->view->message('error', $this->model->error); } mail('titef@p33.org', 'Сообщение из блога', $_POST['name'].'|'.$_POST['phone'].'|'.$_POST['text']); $this->view->message('success', 'Сообщение отправлено Администратору'); } $this->view->render('Контакты'); } |
Модели
Модель должна содержать всю бизнес-логику вашего приложения. Или, другими словами, то, как приложение взаимодействует с базой данных.
Бизнес-логика — это:
Объекты реального мира, которые используются в вашем приложении;
То, как эти объекты взаимодействуют друг с другом;
Набор правил для доступа к этим объектам и для их обновления.
Поэтому, например, Users станет важным объектом в Cribbb, потому что это социальное приложение.
Мы должны хранить информацию о наших пользователях, и поэтому нам нужна модель User и таблица User в базе данных.
Пользователям надо будут вводить имя, адрес электронной почты и пароль, а также другие детали профиля. Чтобы удостовериться, что они вводят правильно отформатированные данные, мы должны проверять их ввод.
Пользователи смогут создавать сообщения. Пользователь может иметь много сообщений, и каждое сообщение должно принадлежать пользователю.
Это основные особенности работы моделей в приложениях MVC. По существу для каждой важной вещи в приложении, вероятно, потребуется модель. Вам, возможно, понадобится проверять данные, используемые в вашей модели, а так же здесь должна быть вся логика, отвечающая за взаимодействие моделей друг с другом.
Main.php |
namespace application\models; use application\core\Model; class Main extends Model { public $error; public function contactValidate($post) { $nameLen = iconv_strlen($post['name']); $textLen = iconv_strlen($post['text']); if ($nameLen < 3 or $nameLen > 20) { $this->error = 'Имя должно содержать от 3 до 20 символов'; return false; } elseif (!filter_var($post['email'], FILTER_VALIDATE_EMAIL)) { $this->error = 'E-mail указан неверно'; return false; } elseif ($textLen < 10 or $textLen > 500) { $this->error = 'Сообщение должно содержать от 10 до 500 символов'; return false; } return true; } |
Подключение и настройка базы данных осуществляется в файле application/config/db.php. Для подключения нужной базы данных прописали настройки сервера баз данных в массив :
return [
'host' => 'localhost',
'name' => 'blog',
'user' => 'root',
'password' => '',
];
View
View.php |
namespace application\core; class View { public $path; public $route; public $layout = 'default'; public function __construct($route) { $this->route = $route; $this->path = $route['controller'].'/'.$route['action']; } public function render($title, $vars = []) { extract($vars); $path = 'application/views/'.$this->path.'.php'; if (file_exists($path)) { ob_start(); require $path; $content = ob_get_clean(); require 'application/views/layouts/'.$this->layout.'.php'; } } public function renderfoto($title, $vars = []) { extract($vars); $path = 'application/views/'.$this->path.'.php'; if (file_exists($path)) { ob_start(); require $path; $content = ob_get_clean(); require 'application/views/layouts/partfolios.php'; } } public function redirect($url) { header('location: /'.$url); exit; } public static function errorCode($code) { http_response_code($code); $path = 'application/views/errors/'.$code.'.php'; if (file_exists($path)) { require $path; } exit; } public function message($status, $message) { exit(json_encode(['status' => $status, 'message' => $message])); }
public function location($url) { exit(json_encode(['url' => $url])); } } |
Дата | Выполнено, % |
---|---|
2020-05-28 18:18:43 | 10 |
2020-05-28 14:39:40 | 100 |
2020-05-28 14:40:02 | 97 |
2020-05-28 15:18:40 | 100 |