Где я могу разместить запрос к базе данных в MVC?

Последние несколько дней я много читал книги и веб-страницы об ООП и MVC на PHP, чтобы стать лучшим программистом. У меня возникла небольшая проблема в моем понимании MVC:

Where do I put a mysql_query?

Должен ли я поместить его в контроллер и вызвать метод для модели, которая возвращает данные на основе предоставленного запроса? Или я должен поставить его в самой модели? Оба варианта, которые я предоставляю, предоставляют полный мусор?

 PeeHaa20 мая 2012 г., 19:21
Я бы сделал запрос (либоmysqli_* или жеPDO) в модели. А такжеno модель не только отвечает за доступ к базе данных.
 PeeHaa20 мая 2012 г., 19:20
& quot; куда положитьmysql_query? & Quot; Вы не: Пожалуйста, прекратите писать новый код с древнимmysql_* функции. Они больше не поддерживаются, и сообщество началоdeprecation process , Вместо этого вы должны узнать оprepared statements и использовать либоPDO или жеMySQLi, Если вы не можете решить,this article поможет выбрать. Если вы хотите учиться,here is a quite good PDO-related tutorial.
 iceteea20 мая 2012 г., 19:23
Так как я все еще не хороший программист, я не знал об этом. Однако в любом случае я хотел остановиться на ORM-Style, который, кажется, основан на PDO. Но вопрос, касающийся mvc, до сих пор неясен: где я могу запрашивать данные из базы данных? Одна общая модель для чтения-доступа к БД или модель для каждой таблицы / какое-либо конкретное действие? Во втором случае: как бы я сохранил код? Это тот случай, когда я бы создал «помощник»?

Ответы на вопрос(5)

mysql_query() и семья; они устарели, поэтому подумайте также об изучении PDO и / или mysqli.

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

Update

Чтобы ответить на вопрос, заданный ОП в комментариях: «одна общая модель для всей базы данных или модель для каждой таблицы / действия?»

Модели предназначены для абстрагирования отдельных таблиц (хотя существуют модели, которые работают исключительно с одной таблицей); например, вместо того, чтобы запрашивать все статьи, а затем запрашивать имена пользователей для авторов, у вас будет одна функция, подобная этой:

function getArticles()
{
    // query article table and join with user table to get username
}

Сколько моделей вы создадите, во многом зависит от того, насколько велик проект и насколько взаимосвязаны данные. Если вы можете определить независимые группы данных, вполне вероятно, что вы создадите модель для каждой группы; но это не трудно & amp; быстрое правило.

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

что многие называют бизнес-логикой. Обычно он отвечает за:

Storing, deleting, updating the application data. Generally it includes the database operations, but implementing the same operations invoking external web services or APIs is not an unusual at all. encapsulating the application logic. This is the layer that should implement all the logic of the application

Вот диаграмма последовательности MVC, которая показывает поток во время http-запроса:

enter image description here

В этом случае Model является лучшим местом для реализации кода, предназначенного для доступа к базе данных.

которые представляют состояние приложения.[Википедия], Таким образом, модель будет местом для вызова базы данных.

В «классическом» (отсутствие лучшего слова atm) Шаблон MVC представление получит текущее состояние из модели.

Не делайте ошибку, говоря, что модель предназначена для доступа к базе данных. Это больше, чем просто доступ к базе данных.

ваша модель не должна содержать код доступа к базе данных. Это принадлежит другому слою вне Model / View / Controller: это называетсяpersistence layer, который может быть реализован с использованиемОбъектно-реляционный картограф такие как популярныеУчение 2 для PHP.

Таким образом, вы никогда не трогаете (мой) код SQL. Постоянный слой позаботится об этом за вас. Я действительно советую вам взглянуть на учебник по Doctrine, это действительно профессиональный способ создания ваших приложений.

Вместо работы с необработанными данными, загруженными из базы данных, вы создаете объекты, которые содержат ваши данные и поведение, связанное с ними.

Например, вы можете иметьUser класс, такой как:

class User
{
    protected $id;
    protected $name;
    protected $privileges;

    public function setName($name) { ... }
    public function getName() { ... }

    public function addPrivilege(Privilege $privilege) { ... }
    public function getPrivileges() { ... }
}

Ваш контроллер будет взаимодействовать только с объектами:

class UserController
{
    public function testAction()
    {
        // ...

        $user = $em->getRepository('User')->find(123); // load User with id 123
        $user->setName('John'); // work with your objects,
        echo $user->getName();  // and don't worry about the db!
        $em->flush(); // persist your changes
    }
}

За кулисами ORM берет на себя всю низкоуровневую работу по выпускуSELECT запрос, создание экземпляра вашего объекта, обнаружение изменений в вашем объекте и выдача необходимыхUPDATE заявление!

Решение Вопроса
Materials on the subject of MVC

которые вы читали, потому что большинство (если не все) книги php, которые касаются MVC, ошибочны.

Если вы хотите стать лучшим разработчиком, я бы порекомендовал вам начать со статьи Мартинга Фаулера -GUI Architectures, Вслед за книгой того же автора -"Patterns of Enterprise Application Architecture", Тогда следующий шаг будет для вас, чтобы исследоватьТВЕРДЫЕ принципы и понять, как писать код, который следуетЗакон Деметры, Это должно охватывать основы =]

Can I use MVC with PHP ?

На самом деле, нет. По крайней мере, не классический MVC, как это былоопределено для Smalltalk.

Вместо этого в PHP у вас есть 4 других шаблона, которые нацелены на ту же цель: MVC Model2, MVP, MVVM и HMVC. Опять же, мне лень писать о различиях еще раз, поэтому я просто сделаю ссылку настарый комментарий мой.

What is Model ?

Первое, что вы должны понять, это то, что Model в MVC - это не класс или объект. Это слой, который содержит множество классов. По существу, слой модели - это все объединенные слои (хотя второй слой там должен называться «Уровень объекта домена», поскольку он содержит «Объекты модели домена»). Если вы хотите прочитать краткое резюме о том, что содержится в каждой части слоя модели, вы можете попробовать прочитатьэтот старый комментарий (перейдите к разделу «примечание стороны»).

& # XA0; & # xA0; & # xA0; & # xA0; & # xA0; & # xA0; & # xA0; & # xA0; & # xA0; & # xA0; & # xA0; & # xA0; & # xA0; & # xA0; & # xA0; & # xA0; & # xA0; & # xA0; & # xA0; & # xA0; & # xA0; & # xA0; & # xA0; & # xA0; & # xA0; & # xA0; & # xA0; & # xA0;Model layer consists of all the 3 concentric circles
Изображение взято изУровень обслуживания статья на сайте Фаулера.

What does the Controllers do ?

Контроллер имеет одну из основных обязанностей в MVC (здесь я собираюсь поговорить о реализации Model2):

Execute commands on structures from model layer (services or domain objects), which change the state of said structures.

Обычно на него возлагается вторичная ответственность: связывать (или иным образом передавать) структуры из слоя модели в представление, но это становится сомнительной практикой, если вы будете следоватьSRP

Where do I put SQL related code ?

Хранение и поиск информации обрабатываются на уровне источника данных и обычно реализуются какDataMapper (не путайте с ОРМ, которые злоупотребляют этим именем).

Вот как будет выглядеть упрощенное использование:

$mapper = $this->mapperFactory->build(Model\Mappers\User::class);
$user = $this->entityFactory->build(Model\Entities\User::class);

$user->setId(42);
$mapper->fetch($user);

if ($user->isBanned() && $user->hasBannExpired()){
    $user->setStatus(Model\Mappers\User::STATUS_ACTIVE);
}

$mapper->store($user);

Как видите, Доменный Объект ни в коем случае не знает, что информация из него была сохранена. И это также не относится к тому, где вы положили данные. Это может быть сохранено в MySQL или PostgreSQL или некоторой базе данных noSQL. Или, может быть, подтолкнул к удаленному REST API. Или, возможно, картограф был издевательством для тестирования. Все, что вам нужно сделать, чтобы заменить маппер, это предоставить этот метод другой фабрике.

Also, please see these related posts: understanding MVC Views in PHP testable Controllers with dependencies how should services communicate between each other? MVC for advanced PHP developers
 02 февр. 2016 г., 15:58
Нет, с::class я имел в видуthis new feature в PHP 5.5. Он очень хорошо работает с пространствами имен и псевдонимами. Когда ты пишешьfoo(ClassName::class), функция получает полное имя класса в виде строки. Таким образом, ваш код не будет заполнен жестко закодированными строками.
 02 февр. 2016 г., 12:09
С::class Концепция вы имеете в виду, что будет класс со статическими методами (например,build Domain(), buildMapper() ), и эти методы вернутсяdomain objects или жеdata mappers экземпляры соответственно?
 01 февр. 2016 г., 21:30
Ваш код должен быть реализован внутри службы?
 02 февр. 2016 г., 06:58
@ dios231 да. Или, по крайней мере, суть этого (обратите внимание, что этому коду уже почти 4 года ... как продвигается ваш 4-летний код). В эти дни я буду использовать DI-контейнер для обеспечения их обслуживания необходимыми зависимостями вместо использования фабрик. А такжеif Я все еще использовал фабрики таким образом, у доменных объектов и картографов данных были бы отдельные фабрики, с::class используется для ввода желаемого продукта.

Ваш ответ на вопрос