我一直在学习模型-视图-控制器范例("MVC"),但有些教程之间存在矛盾,让我感到很困惑。
目前我对这个过程的理解是:
路由器/调度器/前置控制器:
- 虽然在 "MVC" 的名称中没有特别提到,但路由器仍然是非常重要的一个部分。它将请求从原始 URL 转换为具体的控制器。例如,将一个请求路由到应用程序的“问题控制器”,URL 为 www.StackUnderflow.com/question/123。
模型:
这里收集了来自某些存储源(如数据库或 XML 文件)的原始数据。模型作为抽象层,将 控制器 对特定数据的请求转换为(例如)SQL 查询,并将查询结果转换为标准格式,如数据对象。
例如,在上述 /browse/all 情况下:
- “问题控制器”将询问模型:“请提供问题 123 的数据。”
- 模型然后将其转换为 "SELECT * FROM Questions WHERE Id = 123;" 并将其发送到数据库。
- 数据库将返回一个“问题”记录给模型。
- 模型将接受记录,并将其转换为问题数据对象。
- 然后,模型执行同样的操作 "SELECT * FROM Answers WHERE QuestionID = 123;" 并从结果集创建答案对象数组,并将其添加到问题对象的 answers 成员变量中。
- 然后,模型将问题对象返回给“问题控制器”。
控制器:
这是应用程序的工作核心。除了在 模型 和 视图 之间传递消息外,控制器 还负责诸如授权
和应用程序/"业务"逻辑编辑:根据答案,业务逻辑属于模型。在持续的示例中,控制器负责以下事项:
- 确保用户已登录。
- 从 URL 中确定问题 ID。
- 确定要使用哪个视图。
- 发送 HTTP 状态码并在需要时进行重定向。
- 向 模型 请求数据,并将所需数据存储在成员变量中。
视图:
- 总体而言,视图是应用程序中最简单的部分。在基本应用程序中,它主要由 HTML 模板组成。这些模板将包含来自控制器成员变量的数据插入到模板中的占位符中:
例如:
<html>
<head>
<title>
<?php $question->getTitle() ?>
</title>
</head>
<body>
<h1> <?php $question->getQuestionText(); ?> </h1>
<h2> Answers: </h2>
<div class="answerList">
<?php formatAnswerList($question->getAnswers()); ?>
</div>
</body>
</html>
- View 还包含了格式化数据以向用户传递的方法。比如,上面的
formatAnswerList()
方法会获取来自 Controller 的答案数组,并循环调用像是include $markupPath . "/formatAnswer.inc"
这样的代码片段,用于生成答案容器的小模板。