Обычно, фреймворк состоит из контроллеров, моделей и представлений. И рассмотрим типичную его структуру, пройдемся по основным его составляющим и разберем, что в них должно быть, а чего не должно быть.
Контроллеры
Контроллер в PHP фреймворке выполняет обработку запросов. Вот основные принципы, что он должен и чего не должен содержать:
Что должен содержать контроллер:
1. Логика обработки запросов:
* Получение данных из запроса (GET, POST, PUT, DELETE).
* Валидация входящих данных.
2. Взаимодействие с моделями:
* Обращение к моделям для получения, создания, обновления или удаления данных.
3. Подготовка данных для представлений (Views):
* Подготовка данных, которые будут отображены пользователю.
* Определение, какое представление (View) будет использоваться.
4. Вызов представлений:
* Передача данных в представления.
* Рендеринг представлений.
5. Редиректы и ответы:
* Выполнение редиректов при необходимости.
* Формирование ответов в различных форматах (HTML, JSON, XML и т.д.).
Чего не должен содержать контроллер:
1. Сложную бизнес-логику:
* Бизнес-логика должна быть вынесена в модели или сервисы. Контроллер должен быть "тонким" и просто вызывать нужные методы.
2. Длительные операции и обработка данных:
* Эти задачи должны выполняться в моделях или сервисах, чтобы контроллер оставался быстрым и отзывчивым.
3. Логика представлений:
* Контроллер не должен содержать HTML-код или логику, связанную с представлением данных. Это задача представлений (Views).
4. Дублирующийся код:
* Избегайте дублирования кода в разных методах контроллера. Вынесите повторяющиеся части в отдельные методы или сервисы.
5. Доступ напрямую к базе данных:
* Вся работа с базой данных должна идти через модели или репозитории, а не напрямую из контроллера.
Модели
В модели PHP фреймворка должны быть:
1. Атрибуты (свойства) модели: Поля, соответствующие колонкам базы данных, а также вычисляемые или виртуальные атрибуты, которые являются производными от других данных.
2. Методы для работы с данными:
* Методы для получения данных: Например, find(), findOne(), all().
* Методы для сохранения и обновления данных: Например, save(), update().
* Методы для валидации: Например, rules(), которые задают правила валидации данных.
* Методы для работы с отношениями: Например, hasOne(), hasMany() для определения связей с другими моделями.
3. Методы для обработки данных: Например, обработка данных перед сохранением (например, beforeSave(), afterSave()), вычисления, преобразования.
Чего не должно быть в модели:
1. Бизнес-логика: Модели не должны содержать сложные бизнес-правила или логику, связанную с поведением приложения. Это следует вынести в отдельные сервисы или контроллеры.
2. Логика отображения: Модель не должна включать методы или данные, связанные с представлением (например, HTML-разметку, логику формирования шаблонов и т.д.). Это должно находиться в представлениях или контроллерах.
3. Сложные запросы к базе данных: Для сложных запросов лучше использовать репозитории или отдельные сервисы, чтобы модель оставалась простой и легко читаемой.
4. Логика маршрутизации: Модели не должны управлять маршрутами или отвечать за перенаправления, это задача контроллеров и роутеров.
Контроллеры для API и html страниц желательно делать отдельно.
Представление
В идеале, не должна содержать обращений в БД, преобразований данных, каких-то вычислений с данными. Только верстка и получение данных для наполнения страниц. Также, сюда подключаются js/css, специфичные для текущей страницы. Какие-то общие должны подключаться в layouts.
Компоненты/сервисы/репозитории
А тут создаем необходимые классы, относящиеся к проектам, страницам и т.д., где производим все действия над данными после получения из БД и до вывода в представление.
Это обеспечит разделение кода на слои, где каждый слой ответственный за свою часть работы.
В сервисах PHP фреймворка должны быть:
1. Бизнес-логика: Сервисы должны содержать основную бизнес-логику приложения. Это могут быть процессы, которые включают взаимодействие с моделями, внешними API, выполнение сложных расчетов и принятие решений.
2. Работа с несколькими моделями: Если логика требует взаимодействия с несколькими моделями или репозиториями данных, это лучше всего разместить в сервисе, а не в контроллере или модели.
3. Обработка и трансформация данных: Любая логика, связанная с обработкой или преобразованием данных перед их сохранением в базу данных или отправкой в представление, должна находиться в сервисах.
4. Работа с внешними сервисами или API: Интеграция с внешними API, отправка HTTP-запросов, работа с очередями сообщений или любыми другими внешними ресурсами также должна быть реализована в сервисах.
5. Работа с событиями и уведомлениями: Если в вашем приложении используются события (event-driven architecture), их обработка и логика реагирования могут быть реализованы в сервисах.
Чего не должно быть в сервисах:
1. Логика отображения: Сервисы не должны генерировать HTML, JSON или любые другие форматы для вывода. Это задача представлений или контроллеров.
2. Прямое взаимодействие с базой данных: Сервисы не должны напрямую обращаться к базе данных через SQL-запросы. Вместо этого они должны использовать модели или репозитории для работы с данными.
3. Маршрутизация и перенаправления: Логика маршрутизации и перенаправления должна находиться в контроллерах, а не в сервисах.
4. Избыточная логика: Сервисы не должны быть перегружены логикой, которая не связана напрямую с их задачей. Например, валидацию данных лучше вынести в модели или отдельные валидаторы.
5. Работа с сессиями или куками: Управление сессиями и куками должно осуществляться в контроллерах или middleware, но не в сервисах.