2

在 PHP 中使用 MVC 苦苦挣扎。看完后我的担忧变得更大: https ://www.youtube.com/watch?v=RlfLCWKxHJ0

根据 LoD,我的路由器类应该只知道请求 Uri 以加载正确的控制器类。但是,我的 Conroller 应该知道它应该使用哪个 Model 类以及一个 View 类来呈现数据。或者更好的是,Controller 应该知道 ModelFactory 将使用选定的数据存储来处理对象创建。

这一切都打破了我的 LoD。

所以我的问题是:

  1. 路由器应该如何初始化控制器类而不知道它需要哪些参数?即使是 DI 容器,我们也不知道要传递给 Router 内部构造函数的对象参数。如果我们将 DI 容器传递给 Router 构造函数(或任何其他类),我们将返回到 Service Locator。这应该怎么做?

也许这都是错误的,但我的出发点是:

// ... retrieve settings, available languages, start session,...

$router     = new Router($settings);
$router->loadController();

路由器.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 Modelnew View并且必须在构造函数或方法中显式地执行它,这很糟糕。

更多问题:

  1. 我应该如何在 Controller 中获取 Model 类的实例?我应该使用静态方法加载视图吗?
4

1 回答 1

1

首先,模型是一个层,而不是一个特定的类。控制器本身将启动开始处理应用程序业务逻辑所需的类。

看看这些答案。第二个有一些如何调用这些类的例子......

在 MVC 中应该如何构建模型?

在 MVC 应用程序中从模型正确调用数据库?

其次,路由器只是将请求的 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)不要在router类里面发起controller和view。在引导程序中执行此操作。

此外,对于 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];
} 
于 2015-02-19T06:22:39.617 回答