На просторах сети, спустя очень большой объём времени, мне удалось найти самый простой пример шаблона проектирования MVC в PHP. Но я никак не могу понять его логики. Куда двигаться дальше, куда заполнять контент и как это делать в соответствии с шаблоном. Помогите понять. Уже несколько недель пытаюсь понять его, а никак. Сам пример:
class Model
{
public $text;
public function __construct()
{
$this->text = 'Hello World!';
}
}
class View
{
private $model;
public function __construct(Model $model)
{
$this->model = $model;
}
public function output()
{
return '<a href="index.php?action=textclicked">' . $this->model->text . '</a>';
}
}
class Controller
{
private $model;
public function __construct(Model $model)
{
$this->model = $model;
}
public function textClicked()
{
$this->model->text = 'Text Updated';
}
}
$model = new Model();
$controller = new Controller($model);
$view = new View($model);
if (isset($_GET['action']))
{
$controller->{$_GET['action']}();
}
echo $view->output();
Я не понимаю что выполняет команда:
class Controller
{
private $model;
public function __construct(Model $model)
{
$this->model = $model;
}
Я не понимаю кто кого и как загружает. Вообще ничего непонятно(
Давайте попробуй доступно объяснить, свое представление:
MVC
- это идея, не реализация, не набор из 3-ех классов и т.д. Это абстрактная концепция которая помогает решить архитектурные вопросы Вашего проекта предложенным путем.
Самая распространенная версия MVC
выглядит так: поступает запрос (например запрос главной страницы сайта), Ваш скрипт запускает контроллер для главной. Контроллер в данном случае тот кусок кода, который отвечает за логику, логика в данном случае - показать пользователю главную страницу. Для формирования главной страницы - нужно обратиться к части, где хранится визуальное оформление страницы (шаблон), это наш условный View
. Но вот незадача, в этом коде шаблона есть цикл для вывода новостей, новости хранятся в БД, т.к. мы это знаем мы в контроллере дописываем логику которая обратится к Model
и получит новости из бд. Модель - чаще всего представляет класс, который описывает один объект, например класс для работы с новостями. Собственно вот вам и MVC
, если еще проще то можно сказать так: это 3 папочки, где в одной: файлы с логикой конкретных страниц (контроллер); в другой: файлы для работы с БД, каждый файл - отдельный объект (модели); В третьей: файлы с визуальным представлением (шаблоны).
Надеюсь мой пример был достаточно понятен, MVC
- это просто идея, не более. У этой идеи есть куча реализаций и куча модификаций. Например то что я вам написал, это не классическая версия идеи, а доработанная практикой, классика подразумевает точку входа не контроллер, а View
, который запрашивает самостоятельно контроллер и модель. Но и текущий пример это не пик, данная идея имеет ряд минусов, поэтому есть доработки, например HMVC
.
Еще доступнее объяснить так: можно сравнить с автомобилем, есть идея: что двигатель крутит колеса, машина едет - все довольны. Идея простая, но реализаций куча, кто-то ставит двигатель спереди, кто-то сзади; кто-то крутит передние 2 колеса, кто-то задние, а кто-то и все 4. Но идея сохранена...
По вашему примеру, ни о каком MVC
тут речи нет. Ваш пример ближе к классическому представлению, но я покажу более распространенный вариант:
Во-первых, обычно, классы Model
, Controller
используются как родители. Ведь контроллеров, моделей - много, поэтому у каждого свое название. Теперь по порядку:
Модель не модель - если она не содержит запросов к БД (может не содержать запросов (на практике), но в MVC
модель подразумевает работу с БД):
class NewsModel extends Model
{
public $text;
public function __construct()
{
$this->text = <Запрос на получение текста из БД>;
}
}
Отображение - это просто файлы нашего шаблона, класс View
- является условным шаблонизатором
и служит для того, чтобы вставить какие-то данные в этот шаблон:
class View
{
public function render($file, $data)
{
// 1) найти файл $file
// 2) загрузить его содержимое, и вставить в это содержимое $data
// 3) вывести на экран
}
}
Вставить содержимое, поясню что это, пусть есть массив:
$data = ['TITLE' => 'Заголовок'];
, в нашем примере - загрузка главной, шаблон пусть называется -Home.tpl
и в нем есть строка:
<html>
<head>
<title>{% TITLE %}</title>
</head>
<body>
Главная страница
</body>
</html>
Думаю логично что должно произойти, об этом и речь... Прошу не путать, и понимать что в концепции MVC
отображением(view) - считается не класс, а именно наш Home.tpl
Ну и остался контроллер, его задача вызвать модельку, и отображение:
class HomeController extends Controller
{
public function HomeMain()
{
$this->loadNewModel('HomeModel');
$data['TITLE'] = $this->HomeModel->text;
$this->view->render('Home.tpl', $data);
}
}
И осталось вызвать (за это отвечает роутинг):
if (isset($_GET['action']) AND ($_GET['action'] == 'HomeMain'))
{
// загрузить файл с контроллером (HomeController)
(new HomeController)->HomeMain();
}
P.S. Как вы могли заметить в контроллере есть методы: $this->loadNewModel
, $this->view
- эти функции из родительского класса (Controller). Описывать их реализацию я не буду, моя задача донести концепцию и думаю теперь вам все понятно...
Возможно вы в принципе не понимаете, как работают классы и объекты.
А работают они очень просто.
Когда вы создаете класс (давайте возьмем ваш пример) Model
:
class Model {
public $text;
public function __construct() {
$this->text = 'Hello World!';
}
}
В данном классе происходит инициализация свойства $text
- это свойство объекта, а не статичная переменная или константа класса, она вызывается через контекст $this->
, а не через self::, static::
, когда бы она была public static $text;
.
Когда вы определите объект в переменной:
$model = new Model();
У вас к свойству $text
в конструкторе присваивается $this->text = 'Hello World!';
Так-как, свойство public
(чего не рекомендуется делать, а лучше вернуть getter
) вы сможете обратиться к этому свойству после передачи его другому объекту или сразу на экран:
echo $model->text;
В вашем случае, у вас Model
определяется в конструкторе Controller
и View
, значит они принимают Model
, который собран ранее:
$controller = new Controller($model);
$view = new View($model);
А раз мы отправляем в конструкторы классов, у нас будет доступно свойство $text
в обоих классах, но операции можем делать разные.
У вас-же View
выводит на экран, а Controller
изменяет модель как нужно, допустим если вы обратитесь к адресу: ?action=textclicked
вызывает метод $controller->{$_GET['action']}();
у Вас это textClicked
, а дальше у вас в модели, изменится свойство $text
, а View
изменит вывод.
https://phpdelusions.net/articles/mvc
На самом деле мвц - это очень просто. Реально просто. Надо только понимать, с какого конца за него браться.
А браться надо за модель.
Основная проблема в понимании мвц состоит в том, что люди воспринимают эти три компонента как равноправные, и одинаково важные. Но на самом деле единственным важным компонентом является модель. А контроллер и вью - это шелуха, два прыщика на упитанной и румяной модели.
Модель - это вся логика приложения. Это и есть приложение. А контроллер и вью - это всего лишь один из способов обратиться запросить информацию у приложения, причем не обязательные. К примеру, если у нас REST API, то вью отсутствует как класс. А если мы обращаемся к приложению через командную строку, то нам не нужен контроллер.
Отсюда мы можем сделать несколько выводов
Модель - это не один класс, а целый набор классов. Которые и реализуют всю логику приложения.
Контроллер - это код, который служит для коммуникации между браузером и моделью. Он служит только для тансляции http запросов в команды модели.
Вью работает в паре с контроллером, если по запросу надо отобразить HTML.
Оборудование для ресторана: новинки профессиональной кухонной техники
Частный дом престарелых в Киеве: комфорт, забота и профессиональный уход
Есть ли возможность прямо внутри модели App\Post задать значения по умолчанию, например для поля user_id типа:
На данный вопрос уже ответили:
Как взять только одно значение из клетки у котороый всего 6 значений?