【问题标题】:Basic MVC (PHP) Structure基本 MVC (PHP) 结构
【发布时间】:2012-07-27 13:49:51
【问题描述】:

我有一个简单的登录表单的以下数据流。

用户访问控制器 PHP 文件。控制器包括model.php和view.php

用户提交表单,控制器将 POST 数据发送到模型方法,并返回结果。

用户已登录,并由控制器转发到不同的视图(登录成功消息)。

目前我的观点是静态 HTML(没有 PHP),所以这是我的问题。然后向用户传递欢迎信息的正确方法是什么,例如“你好,克雷格!”?

视图是否允许 PHP sn-ps,例如

<?php echo $username; ?> 

因为模型是在控制器文件之前加载的?

谢谢!

编辑:然后允许视图访问特定的类方法是否更好,例如

<?php $user->getUsername(); ?>

而不仅仅是变量?


根据其他答案,我找到了一篇很有用的文章,你可能也感兴趣。

http://www.nathandavison.com/posts/view/7/custom-php-mvc-tutorial-part-5-views

【问题讨论】:

  • 动态内容应该从action传递到view并在那里显示,所以允许在views中使用php变量。
  • 我认为模型包含该类,如果您使用 oops,您可以随时调用方法,因此您将从控制器获取数据,但它会更复杂并使用更多服务器(因为它有更多查询)

标签: php model-view-controller


【解决方案1】:

您必须考虑以下几点:

  • 您不能在 PHP 中执行经典的 MVC。相反,我们有 MVC 启发 模式
  • 在为 Web 实现时,视图和控制器实例之间存在 1:1 的关系
  • MVC 中的模型不是一个类。它是一个层,包含许多不同的类
  • View 不是一个愚蠢的模板,而是一个类的实例,它处理表示逻辑

在基于 Web 的 MVC 中查看

如上所述,MVC 和受 MVC 启发的模式中的 视图 负责表示逻辑。这包括显示错误消息和分页等内容。为此,每个视图可以处理多个模板。

View 从模型层接收信息,并采取相应的行动。来自模型层的信息最终进入视图的方式是 MVC 模式中最显着的差异之一:

  • 经典 MVC 模式

    当模型状态改变时,模型层的结构将信息发送到视图。这是通过observer pattern 完成的。

  • Model2 MVCHMVC 模式

    View 可以直接访问模型层,并能够从中请求信息。这是最接近原始模式的。

  • MVVMMVP 模式

    视图通过控制器接收信息,控制器又从模型层请求它。模式的进一步差异源于在将数据传递给视图之前对数据的处理方式。

您现在所拥有的实际上只是一个模板。与this article 中描述的类似。你最终得到一个结构,它没有地方包含表示逻辑。从长远来看,这将导致表示逻辑被推送到控制器中。

那么那个“欢迎”信息呢?

要显示欢迎信息,您的视图应该从模型层请求当前用户的名称。如果模型层返回某种错误状态,查看选择错误消息模板并插入到布局中。

如果从模型层检索到用户名没有问题,请查看选择包含问候语的模板,在模板中设置值并呈现它。

应按什么顺序加载零件?

控制器应该初始化模型和视图的想法来自对 Web 的 MVC 的非常原始的解释。模式被称为page controller,它试图将MVC直接嫁接到静态网页上。

在我看来,应该是这样的顺序:

  1. 型号

    您初始化结构,通过它您将处理模型层。它很可能是某种服务工厂,它可以让您构建诸如用于登录的Authentication 服务和用于处理文档的Library 服务。像这样的东西。我之前写了有点长的comment on model layer's structure。您可能会发现它很有用。

  2. 查看

    您根据从路由机制收集的信息创建视图实例。如果您正在实现 Model2HMVC,那么您的视图将需要构造函数中的 Service Factory 实例。

    如果你实现的是MVVMMVP,那么视图的构造函数没有特殊要求。

  3. 控制器

    这是您创建的最后一个结构,因为控制器负责将命令发送到视图和模型层,然后它们会更改然后更改两者的状态。因此控制器应该期望在构造函数中同时接收视图和服务工厂。

在 MVC 的基本元素初始化后,调用控制器上的方法,并渲染当前视图。

请记住,这是非常简单的描述。

【讨论】:

  • "因此控制器应该期望在构造函数中接收视图和服务工厂。"澄清一下,您的意思是控制器应该负责实例化(假设为 oop)模型和视图,并从路由中传递它们两个参数 - 对吧?
  • @SamSelikoff,我不确定您对“路由”的理解,但是:,控制器不会初始化视图或模型层结构。视图被注入控制器,模型层元素的初始化在工厂完成。
  • @tereško 我知道对于 Model 2 MVC,View 与模型层交互,但为什么会通过 ServiceFactory 进行交互? ServiceFactory 的目的不是构建某些服务,例如 AuthenticationService,然后将构建的对象 返回 到控制器,然后在控制器中调用它吗?为什么View 需要ServiceFactory - 它不应该构建任何东西,对吧?它只需要来自特定服务的数据..
  • @tgun926 好吧......这可能会很混乱,但我们开始吧。服务本身用于包含*“应用程序逻辑”*(基本上:域之间的交互和持久性抽象)。在这种情况下使用ServiceFactory 实际上是一种解决方法。查看不需要工厂。它实际上需要与控制器共享的AuthenticationService 实例。为了以 OOP 方式促进这种共享,您有两种方法:在“外部”初始化实例并将其传递给两个视图控制器对象 OR ..
  • @tgun926 ,是的。在最简单的实现中,它可能看起来像代码示例,这里:stackoverflow.com/a/15959396/727208 ... 认为在现实世界的情况下它会更复杂一些。 另外说明:,在使用 OOP 相关代码时,您会注意到使用命名空间 Services\Authentication 而不是 AuthenticationService 后缀更好。使自动加载更容易。
【解决方案2】:

你真的可以把任何东西放在你想要的视图中,但为了更好地遵守 MVC 做事方式,你应该将视图中的 PHP 限制为简单的 echos 或 prints(可能非常小循环也是如此,尽管即使是那些也可以在控制器/模型中预先计算)。由于这是获取动态内容的唯一方法,因此说它们不被允许有点愚蠢。

视图的想法是让它具有更多的 HTML 外观,以便前端开发人员或不了解 PHP 的人可以轻松地处理文件而不会感到困惑。

更新

要了解有关 MVC 的更多信息,您可以查看以下任何内容(那里有大量教程):

http://blog.iandavis.com/2008/12/09/what-are-the-benefits-of-mvc/

http://php-html.net/tutorials/model-view-controller-in-php/

http://www.tonymarston.net/php-mysql/model-view-controller.html

要查看使用 MVC 的 PHP 的具体示例,我建议下载一些更流行的框架(例如 CodeIgniterSymfonyDrupal)并查看代码。尝试弄清楚它是如何工作的,然后为一个简单的基于文章的系统重新创建功能。

【讨论】:

  • 当然。这完全是关于关注点的分离,因为你和其他任何人都不知道未来会发生什么(你可能会在你的项目中失去人们,或者决定让只知道 HTML 的人更便宜)。此外,该架构通过严格只允许某些信息进入表示层,从而提高了安全性。
  • 控制器/模型如何在不违反SRP的情况下以视图可以使用的方式预先计算循环?
  • @Mayankswami 如果您想以正确的方式学习,无论您做什么,都不要使用 Codeingiter 作为指导。您可能想看看Symfony2,它是目前更好(不那么糟糕)的之一。
  • -1 建议使用诸如 codeigniter 和 drupal 之类的糟糕代码。并链接到歪曲 MVC 模式的教程。
  • 另外,你为什么链接到 Symfony 1.x 站点?让我猜,你听说过开发者说“symfony 还不错”,但不知道 1.x 和 2.x 版本有多么不同。
猜你喜欢
  • 2019-12-04
  • 1970-01-01
  • 2013-11-24
  • 1970-01-01
  • 2013-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-24
相关资源
最近更新 更多