MVC 中控制器的工作是什么?

发布于 2024-08-18 07:28:02 字数 852 浏览 6 评论 0原文

我正在尝试学习MVC架构。但我无法理解为什么你需要一个控制器。请参阅以下代码了解我的模型和视图。

model.php 连接到数据库并检索帖子。 view.php 将只显示帖子。

model.php

<?php
  $db = mysql_connect("somehostname", "someuser", constant("somepassword"));
  mysql_select_db("somedatabase", $db);

  $result = mysql_query("SELECT post FROM posts WHERE postid='" . $_POST['id'] . "'");
  $row = mysql_fetch_array($result);

  $post = $row["post"];

  mysql_close($db);
?>

view.php

<?php
  require "model.php";
  echo $post;
?>

我将浏览器位置设置为 http://whateverhost/view.php?id=5

这会加载 id 5 的帖子。我在这里不需要控制器。所以我很困惑为什么需要控制器?

注:请结合上面的例子进行解释。我不是一个编程极客,学习 CakePHP 等东西对我来说是难以承受的。

编辑:如果您可以将controller.php添加到上面的代码中,那就太好了。这将帮助我理解控制器的角色以及它如何与模型和视图进行通信。

I am trying to learn the MVC architecture. But I am not able to understand why you need a controller. See the below code for my model and view.

model.php connects to the database and retrieves the post. view.php will just display the post.

model.php

<?php
  $db = mysql_connect("somehostname", "someuser", constant("somepassword"));
  mysql_select_db("somedatabase", $db);

  $result = mysql_query("SELECT post FROM posts WHERE postid='" . $_POST['id'] . "'");
  $row = mysql_fetch_array($result);

  $post = $row["post"];

  mysql_close($db);
?>

view.php

<?php
  require "model.php";
  echo $post;
?>

I set my browser location to http://whateverhost/view.php?id=5

This loads post with the id 5. I did not require a controller here. So I am confused why do you need a controller?

Note: Please explain with reference to the above example. I am not a programming geek and learning things like CakePHP, etc. is overwhelming for me.

Edit: It would be great if you can add controller.php to the above code. That would help me in understanding the role of a controller and how it communicates with model and views.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

愚人国度 2024-08-25 07:28:02

您不需要控制器,因为您的示例很简单。
真实案例场景的示例:

假设您有一个 CAD 应用程序。 CAD 应用程序被安排为 MVC。你有:

  • 一个视图,负责绘制当前模型,并提供可点击的实体。
  • 模型,将当前数据保存为
  • 控制器,控制器的作用是从视图中获取事件,并将它们转换为适当的实体,以便修改模型。

例如,用户单击一个正方形并将其删除。控制器将从视图接收事件,创建一个表示命令的对象(通过命令模式),将其添加到撤消功能队列中并执行命令。然后,该命令将修改模型,但将视图事件转换为修改模型的复杂机制的责任由控制器负责。

当然你可能会说,为什么视图不创建 Command 对象呢?好吧,没有人禁止你这样做,但你最终会得到表示逻辑与操作逻辑的混合。这违背了良好的设计,尽管对于最琐碎的情况,您可以接受这种设计。例如,如果您的 CAD 应用程序允许您将对象列表显示为 3D 表示形式和实体列表,并且您可以从两者中删除,您会清楚地看到这两个视图都实现相同的逻辑来处理命令模式(糟糕的设计),或者它们只是将相同的消息传递给通用控制器(好的设计,MVC)。

You don't need a controller because your example is trivial.
An example from a real case scenario:

Suppose you have a CAD application. The CAD application is arranged as MVC. You have:

  • a view which is responsible for drawing the current model, and provide clickable entities.
  • a model, which keeps the current data to be represented
  • a controller, whose role is to get the events from the view, and convert them into proper entities so to modify the model.

For example, the user clicks on a square and deletes it. The controller will receive the event from the view, creates an object representing a command (via the Command pattern), add it into a queue for undo capability and executes the command. The command will then modify the model, but the responsibility of translating view events into the complex machinery that modifies the model is under the responsibility of the controller.

Of course you could say, why isn't the view creating Command objects then? well, nobody forbids you that, but you would end up having presentation logic mingled with operational logic. This goes against good design, although for the most trivial cases, you could live with this design. For example, if your CAD application allows you to display the list of objects both as a 3D representation and as a list of entities, and you could delete from both, you clearly see that either the two views both implement the same logic to handle the command pattern (bad design), or they just channel the same message to a common controller (good design, the MVC).

三生路 2024-08-25 07:28:02

IMO...

MVC 是一种非常通用的设计模式,不一定说明什么是好什么是坏。有一个模型、一个视图和一个控制器。其中每一项的职责取决于 MVC 的风格,而您选择的 MVC 风格应该取决于项目的复杂性。例如,如果您有一个领域驱动的项目,那么这里其他人给出的示例就不会很好地工作。

因此,从根本上讲:

模型:具有将在视图中显示的数据的对象。这里实际上没有定义 DTO 还是域模型,但我稍后会分享我对此的想法。

视图:是用户看到的内容以及用户交互的方式。这里的任何代码或逻辑都应该直接支持该视图。换句话说,零业务逻辑、零数据访问逻辑、对用户实际看到的任何内容的零知识。无论是 Web 表单、桌面窗口表单还是活动(移动)等...

控制器:可能是这个难题中最模糊的部分。有一点是肯定的,它在视图和“模型”之间进行调解,并决定接下来发生的事情,或者更确切地说,它“控制”流程。但重要的是不要让这种描述太过分。这个东西的作用实际上取决于你对 MVC 的理解。因此,我将分享我在网络环境中看待它的方式;但基本上,只需在控制服务流程和实际执行服务之间划清界限即可。

对我来说,MVC 并不是像某些人可能声称的那样描述 N 层的不同方式。 MVC 中没有层,因为 MVC 实际上位于您的表示层。 MVC 的每个元素实际上都存在于表示层中,MVC 模式只是说您应该将获取数据和显示数据之间的关注点分开:

  • 模型:数据是什么样子。实际上只是视图用来获取其数据的结构
  • 视图:实际显示它
  • 控制器:确定从哪里获取模型的数据,甚至模型本身。

如果您可以接受该声明,那么它应该有助于澄清该模型在这种情况下的真正含义。该模型不是数据访问对象,也不是域模型,因为这些东西都不应该出现在您的表示层中。因此,我们要么使用 ViewModel (MVVM),要么使用 DTO。为了简单起见,我将使用 DTO。

因此,如果我们接受 DTO 作为我们在 MVC 中所说的“模型”时所讨论的模型类型,那么我们从哪里得到它呢?如果控制器不应该干扰数据访问,那么在哪里呢?你的服务层怎么样?您的服务层包含应用程序的所有“操作方法”。它是“Do stuff”层。因此,如果您的视图想要创建用户,它将收集数据并将其交给控制器。控制器决定调用哪些服务来完成任务,并向其发送带有必要数据的请求。服务层以 DTO 进行响应。该 DTO 可以直接使用,也可以添加到另一个模型中(例如,如果调用了多个服务)。

重要的一点是:

  • 控制器对您的域一无所知(如果您有的话),它只知道您可用的服务以及如何调用它们。
  • 控制器绝对不执行任何业务逻辑。例如,如果您需要发送欢迎电子邮件作为 CreateUser 操作的一部分,则控制器不会启动该操作,因为这在技术上是业务规则。它将在您的服务层和域层之间处理。
  • 在我看来,您的控制器也不应该执行任何数据访问。这应该委托给服务层。许多教程倾向于显示控制器与存储库交互,我认为这很好,因为这是一个抽象,但直接数据访问在表示层中的任何地方都应该是绝对不允许的。

同样,这是在网络环境中。如果您在 Android 应用程序中使用 MVC,也许您不会有服务层或域。也许您会与不同种类的物体进行交互。就我个人而言,我总是使用服务或应用程序层,出于多种原因,这些原因可能对其他人有价值,也可能不有价值。

所以在MVC.Net中,控制器更像是一个API;视图和 API 是两种不同的表示媒介,旨在协同工作(后端控制器呈现数据,前端控制器使用该数据构建模型并与视图进行协调)。在 Angular 中,控制器更像是我们在这里讨论的控制器。看起来是层层层层。概念化有点令人困惑,但这个概念实际上从未超越表示层。

但总而言之:控制器“控制”进出系统、进出视图的操作和数据,但实际上并不执行业务。该过程的细节在很大程度上取决于您的项目设计理念。

MVC 与 N -Tier

因此,在此图中,我对概念进行了分组,以在典型的整体应用程序中的 N 层内显示 MVC。通信从左到右运行,不会跳过任何其他层(请参阅:洋葱架构)。在表示层中,控制器了解模型和视图,但视图和模型在大多数情况下一无所知。然而,在许多风格的 MVC 中,包括 ASP.Net 和 MVVM,视图可能知道模型的接口或原型(但不知道模型实例),以便它可以绑定到它。

控制器将处理模型(或在此上下文中的视图模型)的操作,这意味着它可能需要了解域对象和域服务。如果您想要一个更具可重用性的应用程序(例如,您的应用程序可以有多个头:Web API、桌面应用程序和移动应用程序等),您可以选择在表示层和域之间插入应用程序层来提供事务边界和进一步隔离。重要的是,视图不了解/依赖于该架构中的域对象——这就是为什么视图有一个单独的模型。 MVC 中模型的要点是为视图创建模型。。也就是说,它是专门为服务视图而不是领域而设计的模型。只要视图模型从未公开暴露和/或意外序列化,视图模型就可以包装/调整域模型。

顺便说一句,在我看来,Web API 中的“表示层”是序列化的契约(例如 JSON 或 XML)。因此,请相应地对待。

IMO...

MVC is a very generic design pattern that doesn't necessarily say what is good and what is bad. There's a model, a view and a controller. The responsibilities of each of these things depends on the flavor of MVC, and the flavor of MVC you choose should depend on the complexity of your project. For example, if you have a domain-driven project then the examples given by others here wouldn't work very well.

So at its very base:

Model: An object that has data that will be displayed in the view. Whether it's a DTO or a domain model is not actually defined here, but I'll share my thoughts on this in a second.

View: It is what the user sees and how the user interacts. Any code or logic here should directly support the view. In other words ZERO business logic, ZERO data access logic, ZERO knowledge of anything beyond what the user physically see. Either a web form, a desktop window form, or activity (mobile) etc...

Controller: Probably the most ambiguous piece of this puzzle. One thing is for sure, it mediates between the view and the "model" and also decides what happens next or rather, it 'controls' the flow. But it's important not to take that description too far. What this thing does really depends on your understanding of MVC. So I'll share the way I look at it in a web context; but basically, just draw a line between controlling the flow of the service and actually performing the service.

MVC, to me, isn't a different way of describing N-tier, as some people might claim. There are no layers in MVC as MVC is actually IN your presentation layer. Every element of MVC actually lives in the presentation layer and the MVC pattern just says that you should the separate the concerns between getting the data and displaying it:

  • Model: What the data looks like. Really just a structure that the view will use to get its data
  • View: Actually displaying it
  • Controller: Figuring out where to get the data for the model, or even the model itself.

If you can accept that statement, then it should help clarify what the model really is in this context. The model is NOT a data access object and the model is NOT a domain model because neither of those things should be in your presentation layer. So that leaves us with either a ViewModel (MVVM) or a DTO. I'm going to go with DTO for the sake of simplicity.

So if we've accepted DTO as the type of model that we're talking about when we say "model" in MVC, then where do we get it? If the controller shouldn't be messing with data access, then where? How about your service layer? Your service layer contains all the "how to" of your application. It is the "Do stuff" layer. So if your view wants to create a user, it'll collect the data and hand it to the controller. The controller decides which service(s) to call in order to accomplish the task and sends it the request with the necessary data. The service layer responds with a DTO. That DTO can either be used directly or added to another model (if there were multiple services called, for example).

The important points are:

  • The controller doesn't know anything about your domain (if you have one), it only knows about your available services and how to call them.
  • Absolutely no business logic is performed by the controller. For example, if you needed to send a welcome email as part of the CreateUser operation, that would not be initiated by the controller since that's technically a business rule. It would be handled between your service and domain layers.
  • In my opinion, no data access should be performed by your controller either. That should be delegated to a service layer. Many tutorials tend to show controller interacting with repositories which I guess is fine because that's an abstraction, but direct data access should be an absolute no no anywhere in the presentation layer.

Again, this in a web context. If you're working with MVC in an android app, maybe you won't have a service layer or a domain. Perhaps you'll interact with a different breed of objects. Personally, I always use service or application layers, and for several reasons that may or may not be seen as valuable to others.

So in MVC.Net, the controller is more like an API; the view and the API are two different presentation mediums that are meant to work together (the backend controller presents data, the frontend controller builds models with that data and mediates with the view). In Angular, the controller is more like what we're talking about here. Layers of layers of layers, it seems. It's a bit confusing to conceptualize, but the concept never actually moves beyond the presentation layer.

But to summarize: The controller "controls" operations and data going in and out of your system, to and from the view but doesn't actually DO the business. The details of that process depend heavily on your design philosophy for the project.

MVC with N-Tier

So here in this diagram, I've grouped the concepts to show MVC within N-tier in a typical monolithic application. The communication runs from left to right and does not jump over any other layer (see: Onion Architecture). In the presentation layer, the controller knows about the model and the view but the view and the model know about nothing for the most part. However, in many flavors of MVC, including ASP.Net and MVVM, the view might know about the model's interface or prototype (but not the model instance) so that it can bind to it.

The controller would handle the manipulation of the model (or view model in this context) which means it may need to know about the domain object and domain services. You can optionally insert an application layer between the presentation layer and the domain if you want a more reusable application (for example, your application could have multiple heads: a web API and a desktop app and a mobile app, etc.) to provide a transactional boundary and further isolation. It's important that the view has no knowledge/dependency on the domain objects in this architecture -- that's why there's a separate model for the view. The point of the model in MVC is to create a model for the view. That is, it is a model specifically designed to serve the view, NOT the domain. It's ok for the view model to wrap/adapt the domain model so long as it's never exposed publicly and/or accidentally serialized.

On a side note, the "presentation layer" in a web API, in my opinion, is the serialized contract (e.g. JSON or XML). So treat that accordingly.

九局 2024-08-25 07:28:02

我认为在这种情况下可能会用到控制器,我将展示它的代码。

模型:

<?php
  $db = mysql_connect("somehostname", "someuser", constant("somepassword"));
  mysql_select_db("somedatabase", $db);

  $result = mysql_query("SELECT post FROM posts WHERE postid='" . $_POST['id'] . "'");
  $row = mysql_fetch_array($result);

  $post = $row["post"];

  mysql_close($db);

function getPost() {
    return $post;
}
?>

视图:

<html>
<head></head>
<body>
    <input type="submit" onClick="postToScreen();" value="Post">
    <p id="post"></p>
</body>
</html>

控制器:

<?php
    $controllerPost = getPost();
?>

<script type="text/javascript">
function postToScreen() {
    document.getElementById("post").innerHTML="<?php echo $controllerPost; ?>";
}
</script>

我的 JavaScript 生锈了。我认为我的代码是正确的,但在将其放入任何内容之前我会仔细检查它。控制器控制视图的外观,以及在某些情况下模型包含的数据。

I think there could be a use for a controller in this case, and ill show the code for it.

MODEL:

<?php
  $db = mysql_connect("somehostname", "someuser", constant("somepassword"));
  mysql_select_db("somedatabase", $db);

  $result = mysql_query("SELECT post FROM posts WHERE postid='" . $_POST['id'] . "'");
  $row = mysql_fetch_array($result);

  $post = $row["post"];

  mysql_close($db);

function getPost() {
    return $post;
}
?>

VIEW:

<html>
<head></head>
<body>
    <input type="submit" onClick="postToScreen();" value="Post">
    <p id="post"></p>
</body>
</html>

CONTROLLER:

<?php
    $controllerPost = getPost();
?>

<script type="text/javascript">
function postToScreen() {
    document.getElementById("post").innerHTML="<?php echo $controllerPost; ?>";
}
</script>

my javascript is rusty. i think i got that code right but id double check it before putting it in anything. the controller controls what the view looks like, and in certain circumstances, what data the model contains.

愁以何悠 2024-08-25 07:28:02

model.php 在本例中是您的控制器。

如果没有一个好的MVC框架(普通的PHP不是一个好的框架),模型、视图和控制器的角色就不容易区分。

模型是您的数据结构,它持久存在于数据库中。就代码而言,主要由作为类的数据结构组成。

视图仅显示数据。主要是带有一些脚本标签的 html。

控制器控制发生的事情。例如,用户编辑帖子。数据由控制器接收,可能会进行一些修改(添加时间戳、用户 ip)并发送到模型以存储它。然后控制器决定接下来显示哪个视图以及为新视图获取哪些数据。

只是一个小例子。

model.php is in this case you controller.

The roles of model, view and controller are not easy to distinguish if you don't have a good MVC framework (plain PHP isn't a good one).

The Model is your data structure wich is made persistent in a DB. In terms of code if mainly consists of a data structure as a class.

The View just displays the data. Mainly html with some scripting tags.

The Controller controls what happens. For instance, a user edits a post. The data is received by the controller, maybe modified a little bit (added timestamp, users ip) and sent to the model in order to store it. The controller then decides wich view to display next and what data to fetch for the new view.

Just a small example.

迷爱 2024-08-25 07:28:02

恕我直言,在 MVC 中,控制器有两个主要目的

  1. GUI 逻辑或 GUI 触发的任何内容的可测试性。在大多数情况下,您可以相对容易地为控制器编写单元测试,但对于 PHP 或 Windows 窗体等 GUI 来说则要困难得多。前者依赖于浏览器,后者依赖于 Windows Messages,两者都不会让您在编写单元测试时变得更轻松。它与任何其他表示层技术几乎相同。
  2. 表示层或(在某些情况下)控制器的可互换性。在某些情况下,您可以在两个 GUI 中使用相同的控制器(特殊情况下使用“轻”形式,另一种情况下使用“丰富”形式),或者反之亦然(不常见)。

在功能比示例多得多的场景中,您将看到优势。但是您应该决定支持或反对 MVC,并在每种形式的应用程序中使用相同的方法,不要混合使用。我更喜欢 MVC,你几乎总是需要控制器逻辑。

IMHO in MVC the controller has two main purposes:

  1. The testability of the GUI logic or anything the GUI triggers. In most cases you can write unit tests for the controller relatively easy, it's much harder for GUIs like PHP or Windows Forms for example. The former depends on a browser, the later depends on Windows Messages, both doesn't make your life easier when you write unit tests. It's nearly the same with any other presentation layer technology.
  2. The interchangability of the presentation layer or (in some cases) the controller. There are scenarios where you can use the same controller in two GUIs (a "light" form for a special case and a "rich" form for another case) or the other way round (not that often).

In a scenario with much more functionality than in your sample you will see the advantages. But you should decide for or against MVC and use the same approach in every form of you application, don't mix it. I would prefer MVC, you do almost always need controller logic.

伴梦长久 2024-08-25 07:28:02

我只会尝试回答标题中的问题。那么,控制器在 MVC 中的作用是什么?

它的工作是成为模型格式视图格式转换器,以便不具有 UI 驱动的模型和 UI 驱动的数据库结构。

其想法是开发业务逻辑驱动的数据库结构,然后开发独立的UI。现在,当我们添加或移动某些 UI 控件时,我们的模型和数据库结构不应改变。

I will try only to answer the question in title. So, what is the role of an controller in MVC?

It's job is to be a model format to view format translator in order not to have UI-driven model and UI-driven database structure.

The idea is to develop the business logic driven database structure and then develop an independent UI. Now when we add or move some UI control our model and database structure shouldn't change.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文