在 MVC 中,我在哪里放置数据库查询?

最近几天,我大量阅读了关于 PHP 中的 OOP 和 MVC 的书籍和网页,以便我可以成为一个更好的程序员.我对 MVC 的理解遇到了一个小问题:

我应该把 mysql_query 放在哪里?

我应该将它放在控制器中并调用模型上的方法,该方法根据提供的查询返回数据吗?还是我应该把它放在模型本身?我提供的两个选项都是垃圾吗?

解决方案

MVC 主题的材料

您可以列出您正在阅读的书籍,因为大多数(如果不是全部)涉及 MVC 的 php 书籍都是错误的.

如果您想成为一名更好的开发人员,我建议您从 Martining Fowler 的文章开始 - 文章.

控制器做什么?

Controller 在 MVC 中有一项主要职责(我将在这里讨论 Model2 实现):

<块引用>

对来自模型层(服务或领域对象)的结构执行命令,这会改变所述结构的状态.

它通常具有次要职责:将结构从模型层绑定(或以其他方式传递)到视图,但如果您遵循 SRP

SQL 相关代码放在哪里?

信息的存储和检索在数据源层处理,通常实现为DataMapper(不要与滥用该名称的 ORM 混淆).

以下是它的简化用法:

$mapper = $this->mapperFactory->build(ModelMappersUser::class);$user = $this->entityFactory->build(ModelEntitiesUser::class);$user->setId(42);$mapper->fetch($user);如果 ($user->isBanned() && $user->hasBannExpired()){$user->setStatus(ModelMappersUser::STATUS_ACTIVE);}$mapper->store($user);

如您所见,域对象在任何时候都不知道,来自它的信息已被存储.也不是关于你把数据放在哪里.它可以存储在 MySQL 或 PostgreSQL 或一些 noSQL 数据库中.或者可能推送到远程 REST API.或者也许映射器是测试的模拟.你需要做的就是替换映射器,为这个方法提供不同的工厂.

另外,请查看以下相关帖子:

  • 了解 PHP 中的 MVC 视图
  • 具有依赖项的可测试控制器
  • 服务之间应该如何通信?
  • 面向高级 PHP 开发人员的 MVC

The last few days, I have extensively read books and web pages about OOP and MVC in PHP, so that I can become a better programmer. I've come upon a little problem in my understanding of MVC:

Where do I put a mysql_query?

Should I put it in the controller and call a method on a model that returns data based on the provided query? Or should I put it in the model itself? Are both of the options I'm providing total garbage?

解决方案

Materials on the subject of MVC

You could have listed the books you were reading, because most (if not all) php books, which touch on MVC, are wrong.

If you want to become a better developer, i would recommend for you to start with article by Marting Fowler - GUI Architectures. Followed by book from same author - "Patterns of Enterprise Application Architecture". Then the next step would be for you to research SOLID principles and understand how to write code which follows Law of Demeter. This should cover the basics =]

Can I use MVC with PHP ?

Not really. At least not the classical MVC as it was defined for Smalltalk.

Instead in PHP you have 4 other patterns which aim for the same goal: MVC Model2, MVP, MVVM and HMVC. Again, I am too lazy to write about differences one more time, so I'll just link to an old comment of mine.

What is Model ?

First thing you must understand is that Model in MVC is not a class or an object. It is a layer which contains multitude of classes. Basically model layer is all of the layers combined (though, the second layer there should be called "Domain Object Layer", because it contains "Domain Model Objects"). If you care to read quick summary on what is contained in each part of Model layer, you can try reading this old comment (skip to "side note" section).

                            
The image is taken from Service Layer article on Fowler's site.

What does the Controllers do ?

Controller has one major responsibilities in MVC (I'm gonna talk about Model2 implementation here):

Execute commands on structures from model layer (services or domain objects), which change the state of said structures.

It usually have a secondary responsibility: to bind (or otherwise pass) structures from Model layer to the View, but it becomes a questionable practice, if you follow SRP

Where do I put SQL related code ?

The storage and retrieval of information is handled at the Data Source Layer, and is usually implemented as DataMapper (do not confuse with ORMs, which abuse that name).

Here is how a simplified use of it would look like:

$mapper = $this->mapperFactory->build(ModelMappersUser::class);
$user = $this->entityFactory->build(ModelEntitiesUser::class);

$user->setId(42);
$mapper->fetch($user);

if ($user->isBanned() && $user->hasBannExpired()){
    $user->setStatus(ModelMappersUser::STATUS_ACTIVE);
}

$mapper->store($user);

As you see, at no point the Domain Object is even aware, that the information from it was stored. And neither it cases about where you put the data. It could be stored in MySQL or PostgreSQL or some noSQL database. Or maybe pushed to remote REST API. Or maybe the mapper was a mock for testing. All you would need to do, to replace the mapper, is provide this method with different factory.

Also, please see these related posts:

  • understanding MVC Views in PHP
  • testable Controllers with dependencies
  • how should services communicate between each other?
  • MVC for advanced PHP developers

相关文章