简体   繁体   English

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

[英]PHP - Injecting a Model in a Controller properly

I have a simple PHP MVC framework that works this way:我有一个简单的 PHP MVC 框架,它以这种方式工作:

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

(1) StaticFramework is a static "Front controller" that gives the App its default dependecies with the (2) DIC (Dependency Injection Container), which works in a similar way to Pimple . (1) StaticFramework是一个静态的“前端控制器”,它通过(2) DIC (依赖注入容器)为App其默认依赖关系,其工作方式与Pimple类似。 The container can be accessed to change those default dependecies.可以访问容器以更改这些默认依赖项。 For example, the Router class is injected in the App by the DIC .例如, Router类是由DIC注入到App的。

I have a problem here, as it is a MVC application, I have 3 important layers:我在这里有一个问题,因为它是一个 MVC 应用程序,我有 3 个重要的层:

  • Model;模型;
  • View;看法;
  • Controller.控制器。

Injecting the View is easy as it is only a class which has a render method that renders a PHP or HTML file, so I just have to inject one instance of View in my Controller .注入View很容易,因为它只是一个具有render PHP 或 HTML 文件的render方法的类,所以我只需要在我的Controller注入一个View实例。

But injecting the Model in the Controller seems harder.但是在Controller注入Model似乎更难。 Each Model is a separate class and so I can't inject it as I do for the View .每个Model都是一个单独的类,所以我不能像对View那样注入它。 Each Model might also require other dependecies, such as a Database or a XML class for example.每个Model还可能需要其他依赖项,例如DatabaseXML类。

Moreover, I cannot predict which models the Controller will require, as it might need several of them, for example, the ArticleController requires the ArticleModel and the UsersModel .此外,我无法预测哪些型号的Controller都需要,因为它可能需要几个人,例如, ArticleController需要ArticleModelUsersModel

I have a few solutions:我有几个解决方案:

  • Injecting a ModelFactory class in the Controller which will instanciate the models for the Controller .注射ModelFactory类中的Controller将实例化模型的Controller But as each Model might require different dependencies, the ModelFactory must know which one it will need, which doesn't seem possible with a DIC similar to Pimple ;但是由于每个Model可能需要不同的依赖项,因此ModelFactory必须知道它需要哪一个,这对于类似于PimpleDIC似乎是不可能的;
  • Not injecting models in the Controller , and leaving each of them as a separate class, that extends what they need.不是在Controller注入模型,而是将它们中的每一个作为一个单独的类,这扩展了它们的需要。 For exemple, a Model should extend Database if it requires a MySQL connection.例如,如果Model需要 MySQL 连接,它应该扩展Database But it means the model is tightly dependent of its parent, and it makes it impossible for a Model to use mock classes or have several data sources, for example, what if a Model needs both Database and XML ?但这意味着模型紧密依赖于它的父模型,这使得Model无法使用模拟类或具有多个数据源,例如,如果Model需要DatabaseXML怎么办?

So, what is the best way to inject models in the Controller in the case of my framework?那么,就我的框架而言,在Controller中注入模型的最佳方法是什么?

Thank you in advance for your answers.预先感谢您的回答。

Gods below, this makes me really sad.各位大神,这让我很伤心。

  • "static framework" means that the basis of your code is in global state “静态框架”意味着您的代码基础处于全局状态
  • pimple is not a DI container pimple 不是 DI 容器
  • what you describe is not a "view", but a dumb template你描述的不是“视图”,而是一个愚蠢的模板
  • model is a layer, not a class to be injected模型是一个层,而不是一个要注入的类
  • you should learn to use namespaces instead of abusing suffixes你应该学会使用命名空间而不是滥用后缀

</rant>

Your controllers should be interacting with Services .您的控制器应该与Services交互。 The model is the entire thing containing persistence abstractions, domain entities, services, repositories and things that are used to describe the business logic of your application.模型是包含持久性抽象、域实体、服务、存储库和用于描述应用程序业务逻辑的事物的整个事物。

Anyway, to populate your controllers with the necessary services, you should use a proper dependency Injector.无论如何,要使用必要的服务填充控制器,您应该使用适当的依赖注入器。 I would recommend either Auryn (reflection-based) or Symfony DI (configuration based).我会推荐Auryn (基于反射)或Symfony DI (基于配置)。

The way this was solved in ASP.Net MVC is that a request is always directed to a method on a controller (not the controller itself).在 ASP.Net MVC 中解决这个问题的方法是,请求始终指向控制器上的方法(而不是控制器本身)。

The App from your example would look at that method's arguments and invoke specific model binders for each argument's type.您示例中的 App 将查看该方法的参数并为每个参数的类型调用特定的模型绑定器。

This might prove tricky in a language which is not type safe :P在类型不安全的语言中,这可能会很棘手:P

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

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