MVC в PHP
В современном мире программистов только и слышно, что разговоры о MVC. Что же это за штука такая, о которой так много и часто говорят. Давайте разбираться.
Теория MVC
MVC — это сокращение названия шаблона программирования Model-View-Controller. Этот шаблон используется для отделения данных от логики и представления. Допустим, есть у нас пользователь, он будет моделью, так как содержит данные. Чтобы показать данные, мы создаём форму, в которую передаём этого пользователя. Это будет вид. Форма может содержать разные кнопки для изменения данных, то есть модели. Чтобы управлять кнопками, к форме привязывают контроллер, который ждёт нажатия кнопок и меняет модель. Таким образом достигается чёткое разделение обязанностей: модель хранит данные, вид показывает, а контроллер изменяет. При таком подходе одна модель может иметь много разных видов, а они, в свою очередь, контроллеров.
Я специально привёл пример с кнопкой, потому что шаблон MVC очень хорошо работает в пользовательских приложениях, где есть галочки, кнопочки и прочие элементы управления. Мне очень нравится реализация MVC в AngularJS, она действительно удобная и очень простая.
MVC и PHP-фреймворки
Не могу точно сказать, кому пришла «гениальная» идея взять шаблон для десктопа и перенести его в веб, но, начиная с первого Zend Framework, MVC стало уже чем-то вроде стандарта. Все современные фреймворки так или иначе используют этот шаблон. Правда, как это часто бывает, при переносе перевернули всё с ног на голову. Теперь контроллер принимает запросы, инициализирует модель, выполняет какую-то логику и передаёт данные виду. В общем-то и шаблон надо было бы переименовать в CMV, но этого не произошло, все фреймворки гордо именуются MVC.
По факту MVC в современном PHP означает, что HTTP-запрос всегда обрабатывается объектом контроллера, а наличие модели и вида вовсе не обязательно. На мой взгляд, от изначальной идеи MVC остался «огрызок». Если изобразить на схеме, то выглядит это примерно так:

Именно такую схему реализуют фреймворки, гордо именуя её MVC. Где тут модель и вид? А их тут просто нет, кому они вообще нужны.
Проблемы MVC в PHP
Из-за подмены понятий изначального шаблона и «того, что имеем» возникает масса путаниц. Например, где хранить бизнес-логику? Вики говорит, что в модели, а здравый смысл шепчет: «в контроллере». Потому что контроллер есть всегда, а вот модель и вид. как карта ляжет. А вот ещё вопрос, почему на второй схеме есть роутер и действие, а в аббревиатуре никаких букв по этому поводу нет? Наверное, можно придумать массу теорий на этот счёт, но ответ очевиден, это другой шаблон.
Но даже, если отбросить роутеры, действия и прочие нестыковки, то всё равно остаётся один серьёзный вопрос — что является моделью в MVC для веба? Может быть, таблица базы данных, массив, композитный объект? А что делать, если на странице ДВА объекта-модели? На эти вопросы современные фрейворки не любят давать ответы, мол, не нравиться, не ешь. Но при этом активно гнобят тех, кто пытается засунуть логику (например отправку письма или запрос к базе) в контроллер, называя это «плохой практикой».
Хорошая практика MVC по версии фреймворков
Руководство Yii 2 гласит: «Yii приложения организованы согласно шаблону проектирования модель-представление-контроллер (MVC)». На практике там действительно есть папки, которые называются «модели», «виды», «контроллеры». Но, если копнуть глубже, то, вида может и не быть, модель тоже опциональна. Зато всегда есть контроллер, действие и много чего ещё.
Остальные фреймворки, плюс-минус, организованны по тому же принципу: на основании URL определяется контроллер (controller) и функция (action или действие), которая затем вызывается. В качестве аргументов в функцию может передаваться объект запроса или какие-то части URL. В теле функции можно обработать входные данные (через модели или абы как) и подключить вид. Некоторые фреймворки подключают вид сами, более порядочные ждут, когда вид вызовут.
Рассмотрим примеры контроллеров популярных фреймворков:
// Yii2 class PostController extends Controller < public function actionView($id) < $model = Post::findOne($id); return $this->render('view', ['model' => $model]); > > // Symfony 4 class LuckyController < /** * @Route("/lucky/number/", name="app_lucky_number") */ public function number($max) < $number = random_int(0, $max); return new Response( 'Lucky number: '.$number.'' ); > > // Laravel 5 class UserController extends Controller < /** * @param int $id */ public function show($id) < return view('user.profile', ['user' => User::findOrFail($id)]); > > // Zend Framework 3 class AlbumController extends AbstractActionController < public function indexAction() < >>
Разницы между этими контроллерами, на мой взгляд, практически нет. Все они классы, у всех есть функция-действие и все они возвращают «вид» (zf3 делает это неявно). По-большому счёту нет никакой разницы, какой MVC вы будете использовать, все они построены по одному шаблону, который к MVC имеет призрачное отношение.
Проклятье MVC
Когда мне предлагают использовать тот или иной «суперклёвый» фреймворк (в основном это MVC-фреймворки), я сразу уточняю, а куда там можно запихать две тонны и маленькую тележку говнокода. Я пока не видел крупных проектов, в которых был бы только чистый код.
Если контроллер сделан в виде класса, то он должен подчиняться правилам написания классов (принципы SOLID). Это значит, что туда нельзя запихать даже маленькую тележку, не говоря уже о двух тоннах.
На практике люди пихают в свои контроллеры даже не тонны, а мегатонны всего, что только можно и нельзя. По какому-то неведомому принципу контроллер = справочник. Назвался AlbumController , будь добр уметь создавать, обновлять и удалять альбомы. Это хорошо, когда справочник простой и понятный, а что делать, когда нужен справочник-матрёшка? Например, справочник исполнителей в альбоме. А у исполнителей есть свои альбомы, да ещё и с обложками и историей покупок.
Когда задача выходит за рамки документации, то начинается полёт буйной фантазии разработчиков. Обычно такие полёты и порождают монстров в тысячи строк. Это, увы, не редкость в современном веб-MVC.
Некоторые оправдывают использование ООП для контроллеров возможностью писать юнит-тесты и повторно использовать отдельные методы класса. Но в своей практике я не видел ни того, ни другого. А вот тонны говнокода в контроллерах видел. Куда ж его ещё девать? Но это, как мы знаем, фу-фу-фу и так делать нельзя. А куда тогда девать ценнейшее удобрение умственной деятельности сильных мира сего? В модели? Так ведь они тоже классы и подчиняются тем же правилам. Дробить большую какашку на много маленьких и делать вид, что это хэлперы? Наверное можно, но обилие лишних классов само по себе превращает проект в сплошной кусок сами-знаете-чего.
Есть ли жизнь без MVC?
Есть. Не используйте MVC-шаблон для веба в реализации от популярных фреймворков. Изобретайте своё, фантазируйте. Помните, что «своё» не «пахнет».
Для себя я написал свой фреймворк. Там нет MVC, там есть просто файлы-действия, шаблоны и модули. В действия можно запихать хоть десять тонн говнокода, хуже проекту от этого не станет.
Вот так может выглядеть action без MVC:
Module('widgets')->execute('handle.php'); $searchParams = [ 'name' => Request()->get('name'), ]; $pagination = Pagination(); $items = Site\ConsultantRepository::findMany($searchParams, $pagination); $params = []; Template()->render('~/search-form.php', $searchParams); Template()->render('@totalFound', $pagination, $params); Template()->render('@pagination', $pagination); Template()->render('~/list.php' , $items, $pagination->startFrom() + 1); Template()->render('@pagination', $pagination);
/* @var $this ApCode\Template\Template */ /* @var $profile \Site\Consultant */ $profile = $this->argument(0); if ($profile->isDeleted()) < Alert('Пользователь удлён. Вы не можете его редактировать.', 'danger'); > ?> class hljs-title">row widgets"> div class hljs-title">col-md-7"> php echo Widget('consultant.information', $profile, $this->params)?> div> div class hljs-title">col-md-5"> div> div>
А вот пример разработки кабинета без MVC:
Your browser does not support HTML5 video.
Сделать подобный интерфейсе на «обычном» фреймворке, на мой взгляд, очень проблематично. Это хорошо, когда у вас много программистов, включая фронтэндеров, но этот проект я делал один при сильно ограниченном лимите часов разработки. Если бы я попытался идти по пути, например, Yii 2, то только представьте сколько форм, моделей, контроллеров пришлось бы создавать и как-то связывать вместе.
Ну вот опять.
* сумма должна быть пропорциональна размеру вашего достоинства
© 2023 Антон Прибора. При копировании материалов с сайта, пожалуйста, указывайте ссылку на источник.
Model-View-Controller (MVC) — Веб-разработка на PHP
Архитектура веб-приложений в первую очередь определяется самой природой веба — тем, как работает HTTP. Последовательность запрос-обработка-ответ — основа, на которую нанизывается остальное.
Фреймворки идут дальше и разделяют приложение на дополнительные слои уже внутри самого процесса обработки запроса. Без такого разделения код быстро превращается в мешанину из запросов к базе данных, формирований html и логики обработки данных.
Из обработки запроса естественным образом выделяется слой шаблонов, на основе которых генерируется HTML. Этот слой принято называть View — представление. Кроме него выделяют еще минимум два слоя: Model (модель) и Controller (контроллер). Остальное добавляется по мере роста сложности приложения.
Из названий этих слоев получает аббревиатура MVC (Model-View-Controller) — тема нашего урока.
Версии MVC
Существует две разных версии MVC:
- Которая была придумана изначально в сообществе программистов на SmallTalk. Она создавалась под толстые клиенты, а они представляют собой событийные системы, как современные фронтенд-приложения
- Которая называется MVC v2. Буквы в ней те же, но означают местами другое. С такой версией MVC взаимодействие строится по-другому
Архитектурный шаблон MVC задает основную структуру приложения и позволяет коду долго развиваться, при этом он остается удобным в поддержке.
MVC с некоторыми модификациями реализуется всеми веб-фреймворками. Если с представлением всё понятно, то с моделью и контроллером нужно разбираться отдельно.
Контроллер
Контроллеры — это обработчики запросов. Они принимают объект запроса и возвращают объект ответа. В случае Slim контроллеры представлены анонимными функциями, но это не обязательно. В больших фреймворках контроллер — это класс, а обработчики — его методы. Эти методы обычно называют действиями — actions.
При таком подходе вся логика сосредоточена в самих контроллерах, что допустимо в примитивных случаях.
Во всех остальных ситуациях выделяют еще один слой — модель. Это понятие не включает в себя персистентность и базы данных. Среди разработчиков распространено заблуждение, что модель — это база данных и данные внутри неё. Но это не так.
Модель
Слой модели отвечает за бизнес-логику приложения и данные, связанные с ней. Этот слой может быть представлен большим количеством способов, которые зависят от конкретного языка программирования и используемых библиотек.
Самый распространенный вариант — это ORM, но так бывает не всегда. Также часто даже при наличии отдельного слоя модели часть логики все же проникает в контроллеры.
Зачем понадобилось выделять слой модель
Прочтите статью Rails is not your application . Она написана про Rails — популярный веб-фреймворк, который стал прообразом для большинства современных фреймворков на разных языках программирования.
Идея статьи заключается в том, что предметная область, которую мы реализуем внутри сайта, не связана ни с сайтом, ни с фреймворком, который используется внутри.
Действтительно, правила бухгалтерии не могут поменяться в зависимости от выбранного фреймворка. Бухгалтерия и фреймворк не связаны. Бизнес-правила этой области не зависят от существования программирования. С помощью разработки мы можем их выразить в коде, но этот код снова не будет связан с используемым фреймворком.
Код, который описывает предметную область и позволяет с ней работать, можно взять и перенести в другой фреймворк без модификаций. Как видно, на логическом уровне есть граница между кодом, моделирующим предметную область, и кодом, обслуживающим веб-запросы. Но эту границу иногда трудно провести.
Например, к чему относится отправка письма при регистрации, авторизация или восстановление пароля? Если закапываться дальше, то на горизонте возникают понятия Application Logic и Business Logic, а затем и Service Layer. Если интересно, то про них можно почитать самостоятельно.
Самая большая сложность в коде находится именно в этой части приложения. У модели нет четкой структуры. Это не классическое — запрос-обработка-ответ.
Открыть доступ
Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно
- 130 курсов, 2000+ часов теории
- 1000 практических заданий в браузере
- 360 000 студентов
Наши выпускники работают в компаниях:
Что такое MVC? Шаблон проектирования model view controller (MVC) и PHP, Часть 1
Шаблон проектирования Модель-Представление-Контроллер (model view controller — сокращенно MVC) — это шаблон программной архитектуры, построенный на основе сохранения представления данных отдельно от методов, которые взаимодействуют с данными.
Не смотря на то, что схема MVC была первоначально разработана для персональных компьютеров, она была адаптирована и широко используется веб-разработчиками из-за точного разграничения задач и возможности повторного использования кода. Схема стимулирует развитие модульных систем, что позволяет разработчикам быстро обновлять, добавлять или удалять функционал.
В этой статье я опишу основные принципы, а также рассмотрю определение схемы построения и простой MVC PHP пример.
Что такое MVC
Название шаблона проектирования определяется тремя его основными составляющими частями: Модель, Представление и Контроллер. Визуальное представление шаблона MVC выглядит, как показано на приведенной ниже диаграмме:

На рисунке показана структура одностороннего потока данных и пути его следования между различными компонентами, а также их взаимодействие.
Модель
Моделью называют постоянное хранилище данных, используемых во всей структуре. Она должна обеспечивать доступ к данным для их просмотра, отбора или записи. В общей структуре « Модель » является мостом между компонентами « Представление » и « Контроллер ».
При этом « Модель » не имеет никакой связи или информации о том, что происходит с данными, когда они передаются компонентам « Представление » или « Контроллер ». Единственная задача « Модели » — обработка данных в постоянном хранилище, поиск и подготовка данных, передаваемых другим составляющим MVC .
« Модель » должна выступать в качестве « привратника », стоящего возле хранилища данных и не задающего вопросов, но принимающего все поступающие запросы. Зачастую это наиболее сложная часть системы MVC . Компонент « Модель » — это вершина всей структуры, так как без нее невозможна связь между « Контроллером » и « Представлением ».
Представление
Представление — это часть системы, в которой данным, запрашиваемым у « Модели », задается окончательный вид их вывода. В веб-приложениях, созданных на основе MVC , « Представление » — это компонент, в котором генерируется и отображается HTML -код.
Представление также перехватывает действие пользователя, которое затем передается « Контроллеру ». Характерным примером этого является кнопка, генерируемая « Представлением ». Когда пользователь нажимает ее, запускается действие в «Контроллере».
Существует несколько распространенных заблуждений относительно компонента « Представление ». Например, многие ошибочно полагают, что « Представление » не имеет никакой связи с « Моделью », а все отображаемые данные передаются от « Контроллера ». В действительности такая схема потока данных не учитывает теорию, лежащую в основе MVC архитектуры. В своей статье Фабио Чеваско описывает этот некорректный подход на примере одного из нетрадиционных MVC PHP фреймворков:
«Чтобы правильно применять архитектуру MVC, между «Моделью» и «Представлением» не должно быть никакого взаимодействия: вся логика обрабатывается «Контроллером».
Кроме этого определение « Представления » как файла шаблона также является неточным. Но это не вина одного человека, а результат множества ошибок различных разработчиков, которые приводят общему заблуждению. После чего они неправильно объясняют это другим. На самом деле « Представление » это намного больше, чем просто шаблон. Но современные MVC -ориентированные фреймворки до такой степени впитали этот подход, что никто уже не заботится о том, поддерживается ли верная структура MVC или нет.
Компоненту « Представление » никогда не передаются данные непосредственно « Контроллером ». Между « Представлением » и « Контроллером » нет прямой связи — они соединяются с помощью « Модели ».
Контроллер
Его задача заключается в обработке данных, которые пользователь вводит и обновлении « Модели ». Это единственная часть схемы, для которой необходимо взаимодействие пользователя.
« Контроллер » можно определить, как сборщик информации, которая затем передается в « Модель » с последующей организацией для хранения. Он не содержит никакой другой логики, кроме необходимости собрать входящие данные. « Контроллер » также подключается только к одному « Представлению » и одной « Модели ». Это создает систему с односторонним потоком данных с одним входом и одним выходом в точках обмена данными.
« Контроллер » получает задачи на выполнение только когда пользователь взаимодействует с « Представлением », и каждая функция зависит от взаимодействия пользователя с « Представлением ». Наиболее распространенная ошибка разработчиков заключается в том, что они путают « Контроллер » со шлюзом, поэтому присваивают ему функции и задачи, которые относятся к « Представлению ».
Также распространенной ошибкой является наделение « Контроллера » функциями, которые отвечают только за обработку и передачу данных из « Модели » в « Представление ». Но согласно структуре MVC паттерна это взаимодействие должно осуществляться между « Моделью » и « Представлением ».
MVC в PHP
Напишем на PHP веб-приложение, архитектура которого основана MVC . Давайте начнем с примера каркаса:
string = "MVC + PHP = Awesome!"; > > controller = $controller; $this->model = $model; > public function output()< return "" . $this->model->string . "
"; > > model = $model; > >
У нас есть проект с несколькими основными классами для каждой части шаблона. Теперь нужно настроить взаимосвязь между ними:
output();
В приведенном выше примере PHP MVC нет никакого специфического функционала для контроллера, потому что в приложении не определены взаимодействия пользователя. Представление содержит весь функционал, так как наш пример предназначен лишь для демонстрации.
Давайте расширим пример, чтобы показать, как мы будем добавлять функционал контроллера, тем самым добавив в приложение взаимодействия:
string = “MVC + PHP = Awesome, click here!”; > > controller = $controller; $this->model = $model; > public function output() < return 'model->string . "
"; > > model = $model; > public function clicked() < $this->model->string = “Updated Data, thanks to MVC and PHP!”; > >
Мы расширили программу базовым функционалом. Настройка взаимодействий между компонентами теперь выглядит следующим образом:
(); > echo $view->output();
Запустите код и при нажатии на ссылку вы увидите строку для изменения данных.
Заключение
Мы рассмотрели базовую теорию модели MVC , и реализовали на его основе простое приложение. В следующей статье этой серии мы рассмотрим несколько конкретных случаев, с которыми вы можете столкнуться при создании веб-приложений на PHP .
Вадим Дворников автор-переводчик статьи « The MVC Pattern and PHP. Part 1 »
MVC (Model-View-Controller) в PHP
Пока я не стал баловаться программированием на Javа, особо не задумывался над использованием MVC в PHP. Обычно действуешь по своему опыту или как это принято в php-фреймворке (или CMS, не важно). Тем более почти все фреймворки декларируют свою преданность концепции MVC: дескать вот у нас всё сделано правильно, по теории.
После Java, где объектное программирование возведено почти в абсолют, MVC в PHP выглядит уже достаточно «бледно», пытаясь хоть как-то соответствовать этой концепции. Интересно ещё и то, что php-разработчики Model-View-Controller видят по разному и не всегда верно.
Базовая концепция Model-View-Controller
Основа MVC была заложена аж в 1978 году для Smalltalk. Она безумно простая и учитывала реалии того времени. Если чуть утрировать, то Контролёр — это устройство ввода — клавиатура и её обработчики (например драйвера). Как только в Контролёре что-то произошло, например пользователь нажал клавишу, это событие/данные передаются в Модель. Именно в Модели решается что именно нужно сделать с введенной информацией. Например, если нажата Enter, то происходит запуск введенной команды.
После того, как действие выполнено, необходимо как-то его отобразить. За это уже отвечает Вид (Представление) и в простом варианте это обычный монитор, принтер или файл.
Смысл был в том, чтобы выделить из общей кучи кода модули ввода/вывода, оставив основную функциональность программы в виде Модели.
Со временем MVC приняла более абстрактный вид, но общая концепция не изменилась.
- Контролёр указывает модели что нужно сделать.
- Модель выполняет работу.
- Вид отображает/отдаёт результат.
В классических приложениях Model-View-Controller реализуется довольно просто, поскольку состоят из статичного интерфейса. На этапе разработки программы, заранее создается форма, где располагаются кнопки, метки, меню и прочие элементы, которые не будут менять своего расположения, форму или дизайн во время выполнения программы.
Поэтому взаимодействие с пользователем здесь довольно просто реализуется через Контролёр, который понимает, что нажата какая-то кнопка и нужно выполнить определенное действие. Но с PHP всё сложней.
Работа web-приложения
Сайт может взаимодействовать с пользователем разными способами. Например нажатие кнопки, по которому появится всплывающий popup. То есть onClick кнопки должен отслеживаться Контролёром, хотя программно это HTML-код, который вроде как уже Представление.
Однако во всех сайтах есть одна общая черта — все они взаимодействуют через URL-адреса. Любая ссылка — это указание на действие. Например вывести главную страницу, или записи рубрики, или отправить форму по ajax-запросу (там тоже URL). То есть во всех случаях пользователь передаёт своё действие в виде ссылки (http-запроса).
Другой вариант — это действия, где происходит скрытая передача данных через POST (Ajax). Адрес страницы при этом не меняется, хотя обработчик уже должен как-то понимать, что если это post-запрос, то нужно сделать одно, а если get, то просто вывести типовую страницу.
Таким образом, в web-приложении Контролёр должен иметь функции роутинга. Реализация роутинга разнится, но во всех случаях представляет собой в первую очередь разбор URL на части, например с помощью parse_url() и определения метода передачи данных ($_POST и т.п.).
Роутинг в Контролёре определяет дальнейшее действие, которое сильно завязано на структуру приложения. Например можно вызвать функцию, подключить файл или выполнить метод php-класса. См. для примера PHP-роутинг (Routing) для новичков.
В любом случае Конролёру нужно точно знать что дальше делать и какой функциональный модуль будет выполнять эту работу. Также возможен вариант, что Контролёр только передает входящие данные в Модель, которая уже сама принимает решение какой модуль будет выполнять задачу. По сути это одно и тоже, разница лишь в том, где именно будет размещён это «action list».
После того, как управление переходит к Модели, происходит основная работа, то есть то, ради чего посетитель вообще зашёл на сайт. Предположим, что это примитивный вывод даты и времени. В Модели можно сразу же сформировать необходимый html-код для вывода, но это уже будет нарушать концепцию MVC, поскольку Модель должна отдавать только данные, а сама визуализация должна выполняться в Виде.
Вид/Представление по своей сути — это результирующий html-код, который помимо всего прочего, верстается под необходимый дизайн. Скажем, если нужно вывести дату другим цветом, всё что потребуется сделать, так это поменять css-стили в шаблоне. При этом ни Контролёр, ни Модель не меняются.
Проблемы View
Здесь мы сталкиваемся с проблемой: как именно можно передать данные в html-код? Ведь HTML статичен — это не язык программирования, а всего лишь вид разметки документа.
Даже в самой простой реализации, html-шаблон нужно будет сделать в виде php-файла, где придётся смешивать html и php-код между собой. В простых случаях это не проблема, но когда данных для вывода много, то такая смесь уже представляется серьёзной проблемой (низкая читабельность и сложная поддержка).
К сожалению решения этой проблемы не существует, хотя есть методы, которые позволяют упростить написание такого кода (об этом ниже).
Неверное понимание MVC
Очень часто встречаются искаженные толкования Model-View-Controller. Вопрос здесь скорее в практической реализации: PHP очень гибкий язык и позволяет использовать любой подход. Не думаю, что кто-то бросится переписывать свой проект под строгий MVC, но понимание этой концепции может пригодится при создании нового.
Часто под Моделью понимают только работу с базой данных. То есть контролёр вызывает некую функцию/метод Модели, которая возвращает сырые данные. Здесь проблема в том, что кто-то должен эти данные обработать. То есть Модель в этом случае не выполнила всю работу и данные должны быть обработаны либо уже в Представлении, либо в том же Контролёре. В обоих случаях это уже проблема.

Работа с БД — только часть работы Модели. Ни Контролёр, ни Вид не должны ничего знать ни про базу, ни про то, как получаются данные. Для них Модель — это черный ящик, куда можно передать входящие данные и получить готовые.
Другим искажением MVC будет считать Контролёр ответственным за всю логику и работу приложения. С одной стороны, он действительно отвечает за маршрутизацию, но в нём не должно быть логики выполнения. По хорошему, Контролёр даже не должен ничего знать и о Представлении. Когда Контролёру отводится другая роль, то это уже другая концепция: Model-View-ViewModel, Model-View-Presenter и т.п.
Модульность PHP
На практике принято разделять php-код на отдельные файлы. Именно такой подход позволяет избежать загромождения кода и разделить ответственность за каждое действие. Устоявшейся практикой являются не просто отдельные файлы, но и их группировка по отдельным каталогам.
Если проект основан на ООП, то обычно стоит задача организации многочисленных классов. Например в CodeIgniter 2/3 версий каждый класс представлял собой отдельный файл, но все файлы всех классов находятся в одном общем каталоге. Это накладывает некоторые ограничения, поскольку требует размещения всего кода относящегося к классу в один файл.
В CodeIgniter 4 уже используется модульный подход, где классы размещаются в отдельных каталогах и могут состоять из нескольких файлов.
MVC — лишь концепция, поэтому практическая реализация может быть разной. Обычно используют ООП, поскольку это решает проблему пространства имён в PHP, а модульность упрощает поддержку классов. Хотя использование классов и ООП не означает следованию MVC.
View не так прост
Ошибочно принято считать, что html-шаблон — это единственное, что отводится Виду. На самом деле это порождает проблему смешивания html и php-кода, о которой я написал выше.
В простом варианте это может выглядеть так:
model.php $title = 'Титул'; $descr = 'Описание'; $link = 'ссылка'; $link_url = 'адрес'; view.php">
На помощь может прийти php-шаблонизатор, который позволит использовать более простой синтаксис, что улучшает читабельность:
view.php>
>
>">>
Если усложнить задачу, например добавить какое-то условие вывода, то код опять усложнится.
Другой вариант решения — это переместить html-код в сам php-шаблон. То есть это уже будет php-код, который выводит html. Понятно, что здесь уже можно произвольно усложнять логику вывода данных.
view.php echo '' . $title . '
'; echo '' . $descr . '
'; echo '' . $link . '';
Такой подход наиболее часто встречается в CMS-шаблонах. Проблема здесь в том, что вместо html-верстки мы вынуждены заниматься php-программированием.
Также View обычно разбивается на несколько частей/файлов. Например секция HEAD, после компоненты шапки, вывод основного контента, сайдбар и подвал. Здесь главное разделить блоки по функциональному признаку и так, чтобы между ними по возможности не было зависимостей.
Расскажу про ещё один вариант, который я придумал для своей MaxSite CMS. Используется специальный php-класс для форматированного вывода. Вначале в него загружаются данные записи, после этого задается формат вывода, где можно указать дополнительные параметры, а сам вывод осуществляется в виде метода, который делает замены «псевдокода» на основе реальных данных и заданного формата.
// формат $p->format('title', '', '', false); $p->format('cat', ', ', '', ''); $p->format('date', 'j F Y г.', ''); // вывод $p->html(''); $p->line('[title]'); $p->line('[cat][date]'); $p->html(' ');
Таким образом, View не просто вывод шаблона — это обработчик шаблона, который подключает разные модули/блоки/файлы, использует шаблонизатор, а также может содержать сложную логику вывода данных.
Архитектура приложения
Можно ли реализовать строгую MVC в PHP? Если вопрос стоит принципиально, то PHP без проблем реализуется какой-то один из шаблонов проектирования, реализующий MVC: Наблюдатель, Стратегия и Компоновщик и т.д. Всё это взаимодействие между классами в рамках ООП, с которым у PHP нет проблем.
Но с моей точки зрения, более важным будет общая архитектура приложения и практическая реализация отдельных модулей. Например в том же CodeIgniter 2/3 конфигурация представляет собой обычный массив, а в 4-й версии — это уже PHP-класс, который работает с таким же массивом, но уже внутри себя. То есть это более строгое следование теории, но с практической точки зрения — бессмысленное раздувание кода. Или, скажем, во многих случаях удобней и проще воспользоваться обычной require_once() вместо создания сложного загрузчика php-классов.
Поэтому, перед созданием веб-приложения, важно продумать такие нюансы и соблюсти баланс удобства использования и возможность дальнейшего развития своего проекта.
