在PHP中使用MVC挣扎。 看完之后我的担忧变得更大了: https://www.youtube.com/watch?v=RlfLCWKxHJ0
根据LoD,我的Router类应该只知道Request Uri加载适当的Controller类。但是我的Conroller应该知道它应该使用哪个Model类,以及View类来呈现数据。或者更好的是,Controller应该知道将使用选定的数据存储来处理对象创建的ModelFactory。
这一切都打破了我的责任。
所以我的问题是:
也许这都错了,但我的出发点是:
// ... 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类中无能为力,因为我需要调用 new Model , new View ,并且必须在构造函数或方法中明确地执行它,这很糟糕。
更多问题:
答案 0 :(得分:1)
首先,模型是一个层,而不是特定的类。控制器本身将启动开始处理应用程序业务逻辑所必需的类。
看看这些答案。第二部分有一些关于如何调用这些类的例子......
How should a model be structured in MVC?
Properly calling the database from Model in an MVC application?
其次,路由器只是将请求的URL路由到特定的控制器并查看。有不同的方法,但我的路由器检查匹配现有的资源图。基于其他一些事情,它将返回一个成功的资源"页面名称,未找到页面的资源名称或重定向资源等。
来自引导程序的一些基本代码用于说明......
//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)不要启动控制器并查看路由器类内部。在引导程序中执行此操作。
此外,对于Web应用程序,您可能需要也可能不需要DI,服务工厂,甚至不需要使用特定的设计模式。对于大多数人来说,我认为它过度杀伤并增加了不必要的复杂性。
2)控制器将启动类以开始处理业务逻辑(如果必要的话)。
<强> 附加 强>
要向上面添加数据库连接并将其注入控制器,下面是一种方法。
$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];
}