【问题标题】:Can I generate all of the content necessary for multiples pages in a single file with MVC?我可以使用 MVC 在单个文件中生成多个页面所需的所有内容吗?
【发布时间】:2013-01-23 08:46:08
【问题描述】:

我正处于使用 PHP 学习模型、视图、控制器框架的早期阶段。感谢here 找到的教程,我掌握了窍门。据我了解,控制器将调用模型,以便可以运行适当的代码,以便正确呈现可查看的内容。

问题在于,根据那个特定的教程,我似乎必须为每个页面创建一个全新的文件,只是为了调用模型才能使数据可见。

例如,在我的 controller.php 文件中,我有:

require_once("model.php");  

class Controller 
{  
    public $file;
    public $league;

    public function __construct($file, $league)  
    {
        $this->file = $file;  
        $this->league = $league;
    }   


    public function invoke()  
    {
        // Everything that needs to be done in PHP will be done here so that once 
        // whatever file is included, it will just fit in fine and echo out perfectly
        require_once($this->file.".php"); 
    }
}

在我的 model.php 文件中,我有:

class Model 
{
    private $file;
    private $league;

    public function __construct($file, $league)
    {
        $this->file = $file;
        $this->league = $league;
    }

    More code. You get the idea...
}

在我的 teams.php 文件中,我有:

$controller = new Controller("teams", "nba");  
$controller->invoke();

但是,由于teams.php 必须调用模型并且最终需要require_once("teams.php"),所以我必须为视图创建一个全新的文件。因此,现在显示将在teams_display.php 上显示。无论如何,mod rewrite 是否可以帮助促进一个框架,使所有页面都发生在 index.php 文件中,同时给用户一种他们不是的错觉?

【问题讨论】:

  • 你的前端控制器在哪里。这部分通常将处理请求的控制器和进行渲染的模板放在一起。控制器调用模型并将其中的数据传递到模板中。让一个控制器处理多个 URL 是一种从 URL 到控制器进行正确路由的方法。
  • 哦。前控制器对我来说是新闻。我是 MVC 的初学者。直到几天前,我一直在对所有事情使用过程编程。你能给我看一个前端控制器的例子以及它是如何工作的吗?
  • 我建议您不要尝试创建自己的 MVC 框架,而是抓住现有框架之一并进行探索。他们也有很多教程,而且代码质量比任何“构建自己的 MVC 框架”教程都要好得多。至少它们可以作为事物运作方式的示范。
  • 那么,像 CakePHP 或 CodeIgniter 这样的东西?
  • 我在考虑 Symfony 2.1 或 Zend Framework 2。

标签: php model-view-controller mod-rewrite


【解决方案1】:

正如一些人已经提到的。 MVC 不是框架。

MVC 是相当古老的设计模式,originally defined for smalltalk。多年来一直认为它有点evolved 并产生了几个相关的模式,这些模式已被改编用于Web。

MVC 的核心思想是关注点分离。这就是为什么 MVC 和所有受 MVC 启发的模式都由两层组成:

  • 表示层,处理所有形式的接口
  • 模型层,处理存储和业务逻辑。

由于这是两个不同的层,它们不应该知道其他的内部结构。否则你最终会泄漏抽象。

表示层

在实现良好的 MVC 结构中,控制器仅更改模型层的状态(在极少数情况下 - 当前视图实例的状态)。控制器不负责模型层或其中任何结构的实例化。

MVC 中的视图实例应该负责对用户产生响应。在某些情况下,它可能只需要发送一个 HTTP 位置标头,而在其他情况下 - 它通过组合多个模板生成 HTML 输出。从模型层查看它需要的请求数据。

在这种情况下,“用户”不是人,而是与网站通信的浏览器。

模型层

这一层通常由三大组结构组成:

  • domain objects,处理特定业务实体的逻辑
  • 存储抽象(通常 - data mappers),能够存储来自域对象的数据
  • services,包含应用程序逻辑(域对象和存储抽象之间的交互)

表示层通过服务与模型层交互。控制器向它们发送数据,从而改变模型层的状态,而视图实例向它们请求数据。

如果您有兴趣,可以使用here 对模型层进行更长的解释。

附言

避免使用 PHP 框架。它们中没有一个实际上实现了 MVC。相反,它们中的大多数都是纯 Rails 克隆,它本身从未打算成为生产阶段的框架(解释 here)。

【讨论】:

  • 因此,如果控制器不负责模型的任何实例化,我的 teams.php 页面是否应该不包含: $controller = new Controller("teams", "nba"); $controller->invoke();
  • 您的invoke() 方法当前正在执行自动加载。那应该是一个过程,与 MVC 完全无关。您应该考虑改用this function
【解决方案2】:

MVC 不是一个框架,而是一种设计模式。本教程将帮助您了解 MVC 模式,但如果您想使用真正的框架,您可以查看 Zend Framework

在您的情况下 index.php 是入口点,mod rewrite 将所有请求重定向到 index.php,index.php 根据用户请求重定向到适当的控制器。例如http://localhost/teams/nba,'teams' 是控制器,'nba' 是动作。

您必须创建一个 TeamController 并在 控制器 中创建一个“nba”动作。该模型正在处理 DB 层,因此使用 getNbaList 方法创建一个 Team model 来检索所有 NBA 球队。 您必须在您的操作中调用模型,然后您可以将您从模型中获得的所有团队提供给 视图(主要是 html)。

【讨论】:

  • 您的示例 URL 不必映射到具有 nba 操作的团队控制器。它也可能是带有 nba 控制器和默认操作的团队模块。它也可能是一个带有默认操作和“nba”作为参数的团队控制器。这是一个非常重要的特性:URL 可以映射到请求处理的任意组合。
  • 当然有很多可能性,这只是一个简单的例子:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-30
  • 1970-01-01
  • 2014-02-07
相关资源
最近更新 更多