繁体   English   中英

PHP MVC-Controller和View如何访问相同的Model实例?

[英]PHP MVC - How can Controller and View access same instance of Model?

我正在为数据库应用程序开发自己的PHP MVC,我已经完成了该程序,但使用的是可完成所有工作的整体类-MySQL处理,输入处理和显示。 它工作得很好,但是调试和进行更改是一场噩梦! 我最近发现了MVC,并且正在重写该应用程序-目前所有内容都在绘图板上,因此我实际上没有可与您共享的任何代码。

我绊绊的一件事是:我知道Controller应该调用Model以根据用户输入对其进行修改,然后调用View,该View将访问它需要获取其数据的Model并然后显示它。 我希望视图独立于Controller获取数据,而不希望Controller充当中介。 我从Controller的那一行开始,从Model获取数据并将其交给View,但很快就遇到麻烦,因为View需要访问多个Model。

为了解释我坚持的事情,我将举一个例子:


示例:提交带有数据的表单,该表单无法通过模型验证

前控制器:

  • 加载相关控制器并调用ProcessForm操作

控制器:

  • 实例化Model类并调用方法以加载和验证数据

模型:

  • 验证失败:生成错误列表并返回'false'

控制器:

  • 如果模型已返回“ true”,则重定向到“索引”页面
  • 它返回“ false”:调用视图

视图:

  • 实例化Model类并获取数据
  • 显示数据和错误消息

我的问题是,拥有自己的Model实例的View如何在没有Controller自己将其Model实例直接交给View的情况下获取在Controller的Model实例中生成的错误消息? 我想第一个实例需要将消息存储在第二个实例可以检索它们的地方?

我意识到第一个实例可以将其错误返回给Controller,然后可以将其错误传递给视图,而与Model本身无关,但是我仍然想使View独立于Controller。

好吧..所有人的拳头,没有“模型”。 MVC和受MVC启发的设计模式中的模型是一层 ,其中包含许多结构,就像表示层中包含控制器,视图和其他一些东西一样。

除了那部分,您的问题是您拥有这些“模型”的单独实例。 相反,控制器和视图应共享同一工厂,该工厂可以产生并缓存实例。

最佳解决方案是为您提供服务,这些服务代表模型层的各个部分,并且控制器和视图通过这些服务与模型交互。 工厂会在请求时首次初始化服务,然后在重复请求时提供相同的实例。

class ServiceFactory
{
    private $cache = array();

    public function create( $name )
    {
        if ( array_key_exists($name, $this->cache) === false )
        {
            $this->cache[$name] = new $name;
        }
        return $this->cache[$name];
    }
}

这是服务工厂的“极其精简”版本。

在引导阶段,您初始化服务工厂,然后通过将其注入实例实例的构造函数中,从而为当前控制器和当前视图提供实例。

首先,对于控制器和视图,不应有不同的模型实例。 它们都应使用相同的实例。 在这种结构中划分类是更实际的。

领域类(模型)

域类只是保存数据以提供上下文。 例如,您可以拥有一个Person域类。

class Person {
    private $name;
    private $age;
    ...
    public function getName()
    public function getAge()
    ...
}

控制器

控制器是模型和视图之间的桥梁。 它们不应包含任何业务逻辑。 这就是服务的目的。

class PersonController
{
    private personService;

    public function list(Bag bag) {
        bag.add('personList', personService.listAll());
        ...
        Give bag of data to the correct view
        ...
    }
}

服务

服务处理应用程序逻辑。 通常,包含域逻辑的实体与存储抽象之间的交互。

class PersonService {
    public function listAll() {
        ...
        Do the logic to find all persons
        ...
        return $persons;
    }
}

查看

视图仅显示控制器提供给它们的数据。 它没有自己的模型。


它并不能解决所有问题,但至少可以说是对您的结构进行正确选择的一个不错的开始。

Spring框架(Java)具有非常好的MVC实现。 请参阅灵感http://static.springsource.org/spring/docs/3.0.x/reference/mvc.html

无需Controller将自己的Model实例直接交给View

为什么? 这是正常情况,可能您也应该这样做。 模型实例可以在内部存储验证错误,并且如果控制器将同一实例传递给视图,则如何传播此信息的问题将自行解决。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM