PHP - 正确地在控制器中注入模型

时间:2016-09-12 14:17:36

标签: php model-view-controller dependency-injection dependencies inversion-of-control

我有一个简单的PHP MVC框架,它以这种方式工作:

   StaticFramework (1)
          |
          V
         DIC (2)
          |
          V
     HTTPRequest
          |
          V
         App <-> Router
          |
          V
      Controller <-> Model
          |
          V
         View
          |
          V
     HTTPResponse

(1) StaticFramework是一个静态&#34;前置控制器&#34;它为App提供了(2) DIC(依赖注入容器)的默认依赖关系,其工作方式与 Pimple 类似。可以访问容器以更改这些默认依赖项。例如,Router类被App注入DIC

我有一个问题,因为它是MVC应用程序,我有3个重要层:

  • 模型;
  • 视图;
  • 控制器。

注入View很简单,因为它只是一个具有render方法的类,可以呈现PHP或HTML文件,所以我只需注入一个View实例我的Controller

但在Model中注入Controller似乎更难。每个Model都是一个单独的类,因此我无法像View那样注入它。每个Model可能还需要其他依赖项,例如DatabaseXML类。

此外,我无法预测Controller需要哪些模型,因为它可能需要其中的几个,例如,ArticleController需要ArticleModelUsersModel

我有几个解决方案:

  • ModelFactory中注入Controller课程,该课程将为Controller实例化模型。但由于每个Model可能需要不同的依赖关系,ModelFactory必须知道它需要哪一个,而DIC类似于 Pimple
  • 不在Controller中注入模型,并将每个模型作为单独的类,将其扩展到所需的范围。例如,Model如果需要MySQL连接,则应扩展Database。但这意味着模型严格依赖于其父级,并且它使Model无法使用模拟类或具有多个数据源,例如,如果Model需要Database }和XML

那么,在我的框架中,在Controller中注入模型的最佳方法是什么?

提前感谢您的回答。

2 个答案:

答案 0 :(得分:5)

下面的神,这让我很伤心。

  • “静态框架”表示代码的基础处于全局状态
  • 疙瘩不是DI容器
  • 你描述的不是“视图”,而是一个愚蠢的模板
  • model是一个层,而不是要注入的类
  • 你应该学会使用命名空间而不是滥用后缀

</rant>

您的控制器应与Services进行交互。该模型包含持久性抽象,域实体,服务,存储库以及用于描述应用程序业务逻辑的内容。

无论如何,要使用必要的服务填充控制器,您应该使用适当的依赖注入器。我建议Auryn(基于反射)或Symfony DI(基于配置)。

答案 1 :(得分:0)

在ASP.Net MVC中解决这个问题的方法是,请求始终指向控制器上的方法(而不是控制器本身)。

您的示例中的应用程序将查看该方法的参数,并为每个参数的类型调用特定的模型绑定器。

对于非类型安全的语言,这可能会很棘手:P