Должна ли модель mvc в php быть оболочкой PDO? - PullRequest
0 голосов
/ 30 мая 2019

Я пытался узнать о паттерне MVC (без фреймворков), однако, независимо от того, какой материал я читаю в Интернете, он, кажется, постоянно противоречит сам себе.

Мой проект сейчас состоит из формы, которую можно отправить для добавления элемента в базу данных. Другая страница просто перечисляет все элементы, которые находятся в базе данных.

Итак, как я понимаю, моя модель должна подключаться к базе данных (или просто принимать соединение в качестве параметра, что-то еще, что мне не очень понятно) и иметь функции, такие как «saveItem» (которая принимает переменную $ _POST как вход и анализирует его) и "listItems" (который просто возвращает все записи на страницу).

Однако, куда входит контроллер? Теперь я анализирую свои данные в модели. Но если это должно быть сделано скорее в контроллере, что на самом деле делает модель? Я наткнулся на эту страницу. Здесь модель имеет только такие методы, как «select», чьи входные данные - просто SQL-запрос. Но это, по сути, просто оболочка PDO. (Противоречивая информация на этой странице о том, что PDO уже является своего рода оберткой, и на самом деле в этом нет никакой необходимости.)

Полагаю, это имеет смысл, если бы модель была написана просто как обертка, она не имела бы никакого отношения к специфике моего сайта. (Теперь я понимаю, что каждая часть MVC очень специфична для каждого проекта.)

Но тогда кажется, что либо модель, либо контроллер просто не нужны. Любая модель анализирует данные, не оставляя ничего для контроллера, или наоборот.

Буду глубоко признателен за любые разъяснения.

Ответы [ 2 ]

0 голосов
/ 30 мая 2019

Я наткнулся на эту страницу.Здесь модель имеет только такие методы, как «select», чьи входные данные - просто SQL-запрос.Но это, по сути, просто оболочка PDO.

Вы правы.На самом деле, этот пример очень плохо структурирован и не соответствует какой-либо разумной концепции дизайна MVC.Я бы порекомендовал вам полностью игнорировать это и искать лучший пример.

  • Класс DB (предположительно "модель") в этом примере является вспомогательным классом базы данных.Хотя это полезно, но это не модель MVC в любом смысле, и эта тоже не особо хорошо написана.

  • Класс Users (предположительно«контроллер») не является контроллером.На самом деле это больше похоже на модель, так как она пытается (неловко) представить бизнес-объект как класс.

    (Кроме того, расширение вспомогательного класса базы данных - это «запах» дизайна, которого следует избегать- это означает, что каждый объект, который будет создан, создаст свое собственное отдельное соединение с базой данных.)

  • Файл list.php (предположительно, «представление») не очень хорош для просмотра,или.Хотя он обеспечивает некоторую функциональность представления, он также берет на себя роль контроллера, работая с моделью.В большинстве приложений MVC представления реализованы в виде чистых шаблонных файлов - часто даже не исполняемого кода - которые передаются данными контроллером.

Теперь, когда мы правильно разобрали этоужасный урок:

Общая архитектура в приложениях MVC: шаблон активной записи , в котором каждая таблица в вашей базе данных (кроме чисто реляционных таблиц) представлена ​​классом, каждая строка изте таблицы, которые были загружены вашим приложением, представлены экземпляром этого класса, и у каждого из этих экземпляров есть методы, которые можно использовать для манипулирования содержимым этой строки.

Реализация такой архитектуры обычно требует некоторыхформа картографа базы данных или платформы ORM.

0 голосов
/ 30 мая 2019

Я бы воспринял этот вопрос скорее как подлинный запрос, чем как запрос на просмотр какой-либо статьи о SEO-спаме из Интернета. Так и идет:

Прежде всего, вам нужно понять, что термин «модель» неоднозначен. Он может представлять либо бизнес-логику всего приложения , либо просто то, что вы имели в виду - некоторый фрагмент кода, взаимодействующий с базой данных. Чтобы избежать этой двусмысленности, давайте придерживаться первого. Это поможет вам рассчитаться с контроллером. Тогда как мы будем называть «меньшую модель» хранилищем . Термин покрытия для кода, который фактически взаимодействует с базой данных.

У меня очень краткая рецензия, MVC в более простых терминах или структура современного веб-приложения . Это поможет вам обернуть голову вокруг MVC в целом.

Теперь ближе к вашему вопросу.

Оболочка базы данных не может рассматриваться как модель, в любом смысле. Оболочка базы данных - это служба , используемая классом хранения. Таким образом, в вашем приложении может быть как минимум 3 слоя:

  • контроллер. Просто интерфейс для передачи запроса HTTP-клиента в бизнес-модель
  • услуга или помощник. код, который обычно (и неправильно) написан в контроллере. Например, если вам нужно зарегистрировать пользователя, в контроллере вы вызываете метод из пользовательской службы, предоставляя данные, полученные от клиента.
  • класс хранения. Фактический код для взаимодействия с базой данных. Например, это может быть класс User, который содержит такие методы, как register и тому подобное. Этот класс будет использовать PDO (или более продвинутую оболочку, или экземпляр ORM) в качестве переменной класса.

Где последние два должны фактически инкапсулировать бизнес-логику всего вашего приложения.

Самая сложная часть здесь - создание экземпляра класса Storage. Поскольку соединение должно быть выполнено только один раз, должны существовать средства для создания экземпляра объекта UserStorage, обеспечивающего ему соединение с базой данных. Это немного другая проблема, которая решается с помощью контейнера для инъекций зависимости

Для иллюстрации выше с небольшим количеством кода

class UserController extends Controller
{
    public function create($request)
    {
        $userService = $this->serviceContainer->get('user_service');
        $userService->create(
            $request->email;
            $request->password;
        );
    }
}
class UserService
{
    public function create($username, $password)
    {
        // here, userStorage instance was already injected 
        // in the UserService in the controller by DI container
        $this->userStorage->create(
            $request->email;
            $request->password;
        );
    }
}
class UserStorage
{
    public function create($username, $password)
    {
        $sql = "INSERT INTO user VALUES (null, ?, ?)";
        // here, db instance was already injected 
        // in the UserStorage in the controller by DI container
        $this->db->prepare($sql)->execute([$username, $password]);
    }
}

Со всеми этими кажущимися повторениями это можно считать излишне многословным, но есть причины для этого:

  1. в реальном коде есть другие части на каждом этапе, например,
    • Контроллер будет проверять отправленную форму (например, была ли форма фактически отправлена, равны ли пароли и т. Д.) И вызывать View для визуализации формы.
    • UserService может выполнить дополнительные проверки, например, существует ли такая электронная почта
  2. Различные пункты вызова
    • UserService может вызываться из разных мест: из вышеприведенного контроллера, утилиты командной строки или контроллера REST.
    • UserStorage можно вызывать из еще большего количества мест. Например, существует TaskService, в котором перечислены задачи, принадлежащие пользователям, и он, естественно, будет эффективно использовать класс UserStorage. И так далее.

Так что имеет смысл разделить ваши слои таким образом.

Конечно, это просто упрощенная черновая модель, она не реализует ORM, который обычно здесь, и многие другие. Но чем проще эскиз, тем меньше деталей, тем проще понять основную идею.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...