PHP MVC:我真的需要一个控制器吗?

时间:2011-12-03 16:27:42

标签: php model-view-controller controller

我的问题很简单,但(我猜)很难回答:

我的PHP网站/网络应用程序中是否真的需要一个完整的模型 - 视图 - 控制器设计模式?

我无法理解Controller如何对PHP有用,因为每个PHP站点都是在每个请求上动态生成的。因此,在PHP生成站点之后,无法让View(生成的HTML站点在浏览器中)与控制器交互,因为Controller位于服务器端并为每个站点请求生成一次,即使请求是AJAX ...

我完全理解错误吗?

为什么我应该使用任何类型的MVC PHP框架,如Zend或Symphony?

编辑: 例如,假设,应该有一个网站来表示表中的客户列表:

我的模型将是服务器端的一个简单类客户,用于查询数据库。 我的视图将是生成的HTML代码,显示模型(客户列表)。 和控制器?控制器是仅评估GET或POST来调用模型的正确方法吗?

3 个答案:

答案 0 :(得分:5)

  

我是否完全理解了一些错误?

是。

MVC模式不适用于浏览器。浏览器无论如何都会看到HTML。是否使用C ++,PHP,Java或其他任何内容生成此HTML。浏览器不关心用于生成此HTML的设计模式。

MVC是一种设计模式,用于组织和分离代码中的职责。所以不是浏览器,而是开发人员编写代码。这是为了创建更易于维护的代码,您可以在业务逻辑(模型),模型与视图(Controller)和UI(视图)之间的通信之间进行明确分离。

你是否应该在你的网站上使用MVC模式是一个主观问题,我不愿回答,因为它取决于很多因素。

答案 1 :(得分:1)

简答

是。控制器将负责准备要显示的数据以进行呈现,有时还会处理源自客户端的GET和POST请求。它应该将HTML生成留给视图。

长答案

MVC可以非常有助于保持应用程序的可维护性和代码库的合理性。该模式有助于确保代码关注点的分离,并且在大多数情况下将引导您清除“spaghetti php”,其中您的应用程序逻辑与HTML生成纠缠在一起。下面是示例MVC 设置(肯定会有很多变体,但它会给你一个想法):

模型

负责从数据库中提取数据并在请求时保存更改。一个示例可能是表示具有名称和电子邮件字段的用户的php对象。

控制器

负责按摩和操作数据并准备显示。准备好的数据被传递到视图进行渲染,视图只需要知道它需要渲染的数据。例如:控制器可以查看查询字符串以确定要呈现的项目,并将其与其他几个模型查询组合以获取其他数据。

控制器通常还负责处理源自HTML客户端的GET和POST请求,并对数据库应用某种操作。例如 - 处理表单提交或AJAX请求其他数据。

视图

视图负责实际生成用于显示的HTML。在PHP中,视图通常是具有最小逻辑的模板文件。例如,它可能知道如何循环从控制器提供给它的项目或具有一些基本条件。

应用程序MVC与PHP / Python /等。 MVC

从您的其他评论中可以看出,您熟悉在桌面或移动应用程序环境中使用MVC。

两者中MVC的主要区别之一是控制器操纵视图和响应事件的粒度。

例如,在传统应用程序中,控制器可能会侦听源自按钮的点击事件并进行适当的响应。

当您执行服务器端html生成时,您的控制器只是“活着”一段时间,而其准备html通过网络发货。这意味着它只能设置和准备视图以进行显示。

它不是从UI中侦听传统事件,而是以不同的方式对未来的GET和POST请求做出反应。例如,您可能在表单上有一个“保存”按钮,触发对服务器的POST请求(例如yourpage.php?action = save& value = blah)。在处理此请求时,您的控制器可能会访问您的模型并应用更改等。

答案 2 :(得分:1)

我意识到我正在回答一个非常古老的问题,但是,我不相信任何其他问题已经恰当地回答了您的初步问题,并且这有望为其他可能在他们的学习中偶然发现这个问题的人添加一些有用的东西。 MVC。

首先,我将首先说我读了一篇关于PHP社区中存在的关于MVC的混淆的有趣文章,如果你问这类问题,值得一读。

Model-View-Confusion part 1: The View gets its own data from the Model

其次,我不相信你有任何误解,而是你对PHP和MVC有了更好的理解,这让你可以提出问题。仅仅因为某些事物已经被整个社区定义和接受,并不意味着您不应该不时地质疑它的使用。这就是原因。

PHP应用程序中的请求(SESSION状态除外)之间没有内存。每次收到请求时,整个应用程序都会启动,处理请求然后关闭,即后台没有后台运行应用程序线程(至少没有你可以在你的应用程序中使用),从理论上讲,你可以在哪里维护申请状态。这既不好也不坏,只是它的方式。

理解这一点,你可能会开始看到你的想法是正确的。为什么View(允许从模型访问自己的数据)需要一个Controller?简单的答案是,它没有。因此,对于模型的纯显示,View完全有权获取自己的数据(通过模型),它实际上是实现MVC的正确方法。

但是等等。这是否意味着我们不需要控制器?绝对不!我们需要做的是使用Controller来达到其适当的目的。在MVC中,Controller负责解释用户请求并要求Model更改自身以满足用户请求,然后,Model可以通知它的更改依赖关系,View可以自行更新。显然,正如您所知,在PHP Web应用程序的上下文中,View不仅仅是坐着等待更新通知。那么如何实现通知呢?

这是我认为MVC遭到劫持的地方。要通知View它的模型已更改,我们只需将它们指向View的URL即可访问现在更新的Model。很好,但现在我们已经向Controller中引入了一些东西。有些东西说,"嘿,我是一个控制器,但现在我已经了解了View的位置。"我想在这一点上,有人想,"为什么我要重新定向用户?我拥有View需要的所有数据,为什么我不直接将数据发送到View?"并且爆炸!我们在这里。

让我们回顾一下。

  1. 视图CAN可直接在MVC中访问模型
  2. 模型包含域对象的业务逻辑
  3. Controller并非旨在提供对模型的View访问权限或充当任何类型的介体
  4. Controller接受用户请求并对其进行更改
  5. 视图不是UI / HTML,也就是使用模板的地方
  6. 一个实际的例子 为了解释我所描述的内容,我们将在今天的大多数网站中查看一个简单的,常见的功能。查看单个登录用户的信息。为了证明MVC方法的结构,我们将在这里从代码中留下许多东西。

    首先假设我们有一个系统,当我们对GET发出/user/51请求时,它会被映射到我们的UserView,并注入相应的依赖项。

    让我们定义我们的课程。

    // UserModel.php
    class UserModel {
        private $db;
    
        public function __construct(DB $db) {
            $this->db = $db;
        }
    
        public function findById($id) {
            return $this->db->findById("user", $id);
        }
    }
    
    // UserView.php
    class UserView {
        private $model;
        private $template;
        private $userId;
    
        public function __construct(UserModel $model, Template $template) {
            $this->model = $model;
            $this->template = $template;
        }
    
        public function setUserId($userId) {
            $this->userId = $userId;
        }
    
        public function render() {
            $this->template->provide("user", $this->model->findById($this->userId));
            return $this->template->render();
        }
    }
    

    那就是它!您根本不需要控制器。但是,如果您需要对模型进行更改,则可以通过Controller进行更改。这是MVC。

    <强>声明

    我不主张这种方法是正确的,任何开发人员在任何时间点采取的任何方法都是错误的。我坚信任何系统的架构都应该反映其需求,而不是任何必要的特定风格或方法。我试图解释的是,在MVC中,View实际上允许直接访问它自己的数据,而Controller的目的不是在View和Model之间进行调解,而是旨在接受用户请求这需要操纵特定模型并请求模型执行此类操作。