Борьба с MVC в PHP.
Мои опасения выросли еще больше после просмотра этого:
https://www.youtube.com/watch?v=RlfLCWKxHJ0
Согласно LoD мой класс Router должен знать только Request Uri для загрузки соответствующего класса Controller. Однако мой Контроллер должен знать, какой класс Model он должен использовать, и класс View для представления данных. Или, лучше, Controller должен знать ModelFactory, который будет обрабатывать создание объектов с использованием выбранного хранилища данных.
Это все ломает LoD для меня.
Итак, мой вопрос:
Может быть, это все неправильно, но моя отправная точка:
// ... retrieve settings, available languages, start session,...
$router = new Router($settings);
$router->loadController();
router.php
class Router
{
public function __construct(Settings $settings)
{
$this->settings = $settings;
}
// some other methods
public function loadController()
{
try
{
// Loading controller
$controller = $this->getController();
if (is_callable(array($controller, $this->method)) == false)
$this->method = 'init';
// Running controller
$controller->{$this->method}();
}
catch (Exception $e)
{
$e->displayMessage();
}
}
}
И с этого момента я ничего не могу сделать внутри моего класса Controller, потому что мне нужно позвонить новая модель, новый вид и делать это явно внутри конструктора или метода, что плохо.
Больше вопросов:
Во-первых, модель представляет собой слой, а не определенный класс. Контроллер сам инициирует классы, необходимые для начала обработки бизнес-логики вашего приложения.
Посмотрите на эти ответы. 2-й имеет несколько примеров того, как эти классы можно назвать …
Как модель должна быть структурирована в MVC?
Правильно ли вызывать базу данных из Model в приложении MVC?
Во-вторых, маршрутизатор просто направляет запрошенную ссылку на определенный контроллер и просматривает. Есть разные способы сделать это, но мой маршрутизатор (ы) проверяет совпадения с существующей картой ресурсов. Основываясь на нескольких других вещах, он либо вернет успешное имя «ресурса» для страницы, имя ресурса для страниц, которые не найдены, либо ресурс для перенаправления и т. Д.
Некоторый базовый код из начальной загрузки для иллюстрации …
//snip
$routeLoader = new \Routing\RouteLoader();
$match = $routeLoader->getMatchedRoute( $request['pageName'] );
$router = new \Routing\Router( $request );
$resource = $router->getResource( $match );
//snip
$viewName = '\View\\' . $resource . 'View';
$controllerName = '\Controller\\' . $resource . 'Controller';
$view = new $viewName();
$controller = new $controllerName( $view, $request );
$controller->{$router->getCommand()}();
$view->response();
Итак, чтобы прямо ответить на ваши вопросы ..
1) Не запускайте контроллер и не просматривайте класс маршрутизатора. Сделай это в начальной загрузке.
Кроме того, для веб-приложений вам может потребоваться, а может и не потребоваться DI, сервисная фабрика или даже найти необходимость использования определенного шаблона проектирования. Для большинства я считаю это излишним и добавляет ненужные сложности.
2) Контроллер инициирует классы, чтобы начать обработку бизнес-логики (если это даже необходимо.)
ДОПОЛНИТЕЛЬНЫЙ
Чтобы добавить соединение с базой данных к вышеуказанному и вставить его в контроллер, ниже приведен 1 способ сделать это.
$DCM = new \Database\DatabaseConnectionManager( new \Config\DatabaseConfig() );
$AppCache = new \Cache\AppCache();
$DAM = new \DataAccess\DataAccessManager( $AppCache, $DCM );
В приведенном выше коде объект DataAccessManager будет отвечать за извлечение данных либо из первого кэша, либо второго из базы данных. Этот объект $ DAM теперь может быть введен в контроллер, вот так …
$controller = new $controllerName( $DAM, $view, $request );
Вместо того, чтобы подключаться к базе данных в начальной загрузке и передавать соединение вокруг приложения, я предпочитаю использовать DataAccessManager, который будет устанавливать соединение только тогда, когда это действительно необходимо. Как только это необходимо, объект PDO (или любой другой объект) инициируется и сохраняется в объекте, который необходимо извлечь и использовать снова, если это необходимо. Я также могу подключиться к другим базам данных, если это необходимо ..
// method from DataAccessManager class
private function connectToDatabase( $server = 'slave' )
{
if (!array_key_exists( $server, $this->dbObject )) {
// use the DataConnectionManager to connect and store the connection here
$this->dbObject[$server] = $this->DCM->connect( $server );
}
return $this->dbObject[$server];
}
Других решений пока нет …