Я думаю, что вы пытаетесь создать структуру, которая слишком тесно связана с именами и понятиями. Я обнаружил, что имена и понятия в идиоме Model-View-Controller не определены жестко. Я также обнаружил, что код, работающий в этой парадигме, должен иногда уметь изменять правила.
@ duffymo имеет очень важное замечание относительно компонента Model: модель не является хранилищем данных, она просто имеет хранилище данных. Если это не ясно, другой способ думать об этом - посмотреть, каким должен быть экземпляр каждого из них. Экземпляр объекта «хранилище данных» представляет ресурс, который обеспечивает доступ к произвольному количеству данных. Обычно это соединение с базой данных. Экземпляр «модельного» объекта обычно представляет собой дискретную идентичность с несколькими частями данных. Обычно он представляет строку базы данных в таблице, но это может быть строка в текстовом файле или один файл в хранилище файлов.
Применив один и тот же вопрос к контроллеру и представлению, вы увидите, что часть модели - это совсем другое животное. Хотя обычно одновременно существует только один объект Controller и один объект View, вполне вероятно, что одновременно существует несколько различных объектов Model разных типов.
К сожалению, я также знаю, что многие MVC-среды определяют «Модель» как уровень API, за которым вы выполняете операторы SQL. В этих средах «Модель» - это статический класс или отдельный экземпляр, и он не делает ничего, кроме как обеспечивает практически бесполезное разбиение пространства имен. И многие программисты считают, что это должно иметь смысл и бороться с этим. Вот почему я рекомендую вам не использовать названия и понятия идиомы MVC.
Мой предпочтительный способ написания структурированного PHP только кивает на парадигму MVC. В верхней части находится логика диспетчера и контроллера, а в нижней части - разметка HTML. Это хорошо работает, потому что контроллеры и представления часто тесно связаны между собой, и помещение их в один и тот же файл очень сильно мешает PHP. Да, требуется дисциплина, чтобы не выполнять действия контроллера в коде представления, но я бы предпочел сделать это сам, чем заставить систему заставить меня это делать. Эти страницы не являются самостоятельными, однако они содержат много общей логики и могут импортировать такие вещи, как облегченная диспетчерская система, или даже вызывать целые серии общей логики контроллера.
Но главное, что обеспечивает общая логика, это уровень абстракции данных - в основном уровень модели, как описано в верхней части моего ответа. Уровень абстракции данных, который я написал, состоит в основном из трех вещей: обработчик базы данных, объект «объект» и объект «коллекция».
Обработчик базы данных - это хранилище данных для всех объектов, которые находятся в базе данных. Его основная цель заключается в том, чтобы все операции с базой данных, которые не выполняют запрос и не получают ответ, были в одном месте. Большинство вызовов базы данных находятся в ядре объекта. Обработчик базы данных ничего не знает о ядре объекта: он просто берет SQL и возвращает наборы результатов.
Два других объекта предназначены для подкласса и не будут работать, если будут созданы сами. Используя наследование и специальное расширенное объявление (сделанное методом статического класса), они знают, как превратить
база данных данных в объект. Экземпляр унаследованного объекта «объект» представляет одну строку объявленного класса. Ему присваивается идентификатор при создании экземпляра, и он будет запрашивать базу данных, когда ему необходимо получить одну строку данных. Он также отслеживает изменения и может сделать однорядное ОБНОВЛЕНИЕ, когда ему сказано. API, который он представляет, полностью лишен SQL: у объекта есть поля you -> get () и -> set (), и вы можете -> save (), когда закончите.
Объект "коллекция" знает, как получить отфильтрованный список строк конкретного объекта, и знает, как соответствующим образом превратить его в отдельные объекты, каждый из которых функционирует так же, как они были созданы индивидуально. (Объект коллекции также поддерживает сам объект, но я редко использую эту функцию, поскольку в настоящее время она имеет некоторые ограничения реализации. И я обнаружил, что большинство программистов с трудом понимают эту проблему.)
Большинству объектов требуется только основной код наследования и объявления для их конкретной таблицы.
Конечным эффектом является то, что код контроллера делает очевидные вещи, подобные этому:
$ticket = Ticket::Create($ticket_id);
$ticket->set('queue', $new_queue);
$ticket->set('queue_changed', date('Y-m-d H:i:s'));
$ticket->save();
... вместо чего-то непрозрачного, например:
TicketModel::ChangeTicketQueue($ticket_id, $new_queue);
Этот подход также позволяет вам кодировать вещи в объекте Ticket, которые могут обновлять другие поля или другие объекты при изменении поля queue
, и это всегда будет происходить при изменении этого поля, вместо того, чтобы не забывать делать это в каждая функция, которая может изменить очередь заявки. Это также означает, что вы можете добавить другие методы в Билет: вероятно, для $ticket->get_queue()
будет иметь смысл сделать return TicketQueue::Create($this->get('queue'));
для вас. Объектно-ориентированное программирование во всей красе! :-)
Итак, чтобы окончательно ответить на ваш вопрос, я бы рекомендовал none подходов в вашем вопросе. Ваши объекты модели должны представлять унифицированный API для кода контроллера, и они сами должны определить, как они хранят свои данные. Если он находится в базе данных, то для этого им необходимо организовать свои собственные вызовы. Но модель не является хранилищем данных: тем не менее, она может иметь единицу.