【问题标题】:MVC: Nested Views, and Controllers (for a website)MVC:嵌套视图和控制器(用于网站)
【发布时间】:2011-02-20 04:23:15
【问题描述】:

我即将使用 MVC 模式做一个 PHP 网站。我没有使用框架,因为该站点相当简单,我觉得这将给我一个直接了解该模式的好机会。我有几个问题。

问题 1:我应该如何组织我的观点?我正在考虑有一个页面视图,它有页眉和页脚,并且允许在它们之间嵌套一个内容视图。

问题 2:如果我有 5 个内容页面,我是否应该制作 5 个不同的视图来用作嵌套在页面视图中的内容?或者,我应该让它们都扩展一个名为 AbstractContent 的抽象视图吗?

问题 3:控制器呢?我认为至少应该有一个主控制器。但是那么请求从那里去哪里呢?到另一个控制器?或者我应该只调用页面视图并保留它吗?我认为控制器应该处理输入,可能修改模型并选择视图。但是,如果嵌套在控制器调用的视图中的其中一个视图需要解析额外的输入怎么办?

问题 4:是否允许控制器向视图传递参数?或者控制器是否应该简单地修改模型,这会影响视图?还是该模型仅用于数据库访问和其他类似的事情?

【问题讨论】:

    标签: php model-view-controller web view controller


    【解决方案1】:

    1 - 这是一个偏好问题。最简单的方法是拥有一个单独的页眉和页脚文件。然后你可以在你的页面控制器中做这样的事情

    $title="Page Title";
    $var1 = 'var1';
    $var2 = 'var2';
    $var3 = array("asdf","adsfasdf","234");    
    
    include(HEADER); //$title is in header
    include(DIR_VIEWS . 'page.php'); //$var1/2/3 are in page.php
    include(FOOTER);
    
    // variable were created before pages were included so they will be set in the templates
    

    如果你要走嵌套路线,你将不得不开始摆弄 str_replace 并开始走向模板引擎,超出了这个答案的范围。

    2 - 无需创建视图对象。 “视图”可以只是文件系统上的一个文件,其中包含该视图的 html。就像我上面的例子一样。这些页面也可以包含基本的 php 到循环/回显变量。

    3 - 您正在描述一个前端控制器(有时称为调度程序或路由器)。这真的是要走的路。有几种创建前端控制器的方法。

    您可以拥有一组指向控制器的 url。

    $routes = array (
    
        '~^/home/$~' => 'home.php',
        '~^/contact/$~' => 'contact.php',
        '~^/blog/.*?$~' => 'blog.php'
    
    );
    

    或者您可以使用 url 中的第一个“目录”作为控制器名称并从您的控制器目录中加载该文件。

    4 - 控制器的全部意义在于从模型中获取信息并将数据传递给视图。


    已编辑以供评论

    如果您希望一堆视图有一个侧边栏,您只需将该视图包含在另一个视图中即可。例如:

    <div id="content">
        <p>lorem ispum stuff</p>
    </div>
    <?php include(DIR_VIEWS . 'sidebar.php');
    

    只需确保在“控制”带有侧边栏的页面的控制器中包含一些用于侧边栏功能的代码:

    if ( $_GET['keywords'] ) {
        $sidebar_search_results = get_search_results($_GET['keywords']);
    }
    // this code should be in a file that you include
    

    $sidebar_search_results 可以是您的侧边栏视图解析和显示的结果数组。

    【讨论】:

    • 对于嵌套视图,我认为我的问题是:如果我有 4 个非常不同的视图怎么办 - 但它们都共享一个共同的元素(比如说一个新闻面板)。我想让“新闻”面板成为 4 个主要视图中的每一个中的嵌套视图。问题是新闻面板需要从某个地方获取数据。如果新闻面板有搜索功能呢?然后它也需要一个控制器,以确保正在处理搜索参数。我怎么能做那样的事?
    • @Galen 的“已编辑评论”:对于嵌套视图,其想法是视图应该是相当独立的——也就是说,我希望能够立即将它们切换出去。不过,这样一来,我在顶部的控制器中添加了不必要的代码,如果我有太多深度嵌套的视图,这可能会变得非常烦人。你怎么看?
    • 如果您有搜索功能,您将需要代码来进行搜索。无论如何,那都必须在控制器中。如果需要切换侧边栏的布局,只需用新代码覆盖sidebar.php即可。
    • 明白了。我猜如果多个控制器使用相同的搜索代码,只需将该代码放在函数文件或其他东西中即可。谢谢:)
    • 记住这只是一种方法,而且很简单。
    【解决方案2】:

    问题一:

    这确实是一种方法,也是我一直使用的方法。

    问题 2:

    让视图尽可能简单。我倾向于只创建 5 个单独的视图(纯 php 文件)。

    问题 3:

    在正常的 mvc 模式中,有一个前端控制器(操作系统只是一个引导文件,index.php)执行一个控制器。

    在 HMVC 中,控制器可以向其他控制器发送额外的请求。

    问题 4:

    普通的 MVC 模式适用于普通的应用程序,其中视图是持久的,并且可以观察模型。对于 Web 应用程序,这是不可能的,因为每个请求都会重新加载所有内容。所以最常用的模式就是让控制器把参数传给视图。

    【讨论】:

    • +1,谢谢。 1、2、3有意义。对于 4,很高兴知道我可以将参数传递给视图。但是,我也可以让视图与模型交互以从数据库获取信息,还是应该由控制器提供?另外 - 每个视图是否特别需要一个控制器和一个模型?我更多地考虑每个视图有一个控制器,我需要抽象的数据库中的每个事物都有一个模型。
    【解决方案3】:
    1. 考虑一下您希望 HTTP 响应的样子:带/不带导航的完整页面、用于打印的剥离页面、JSON 和 XML 响应、索引/站点地图。在您感觉网站正在形成之后,添加越来越多的快捷方式,以便用尽可能少的代码获得响应。
    2. 如果页面布局相似,我会使用相同的视图并将内容从模型(可能是数据库)加载到其中。
    3. 查看Front Controller pattern:您应该始终能够在单个入口点与请求相交。我会在你的控制器前面分层放置一些东西,然后每个“主页”(论坛、博客、新闻)都有一个控制器。这足以控制,但您必须决定哪些块对您来说足够大/小。
    4. 控制器负责传递到视图中的所有内容。控制器应该从模型中获取数据、设置和其他东西,然后传递给视图。

    【讨论】:

    • 这很有帮助; +1 :)。但我认为控制器对模型进行了更改(即更新数据库等),而视图从中获取数据(如下图所示:en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller)。不是这样吗?
    • 我现在更仔细地阅读,您说“我认为控制器应该处理输入,可能修改模型并选择视图。”我同意,所以是的!
    • 那么视图应该可以直接从模型中获取数据吧?例如,我可以让控制器修改一些用户设置,并让视图从模型中获取这些设置(mdoel 会为此提供一个易于使用的界面)吗?
    • 我宁愿在模型和视图之间始终有一个控制器。我猜这两种方法都是有效的,但我更愿意只在视图中处理与 UI 相关的逻辑,而不是负责(直接)对模型进行新调用。
    猜你喜欢
    • 1970-01-01
    • 2012-09-18
    • 1970-01-01
    • 1970-01-01
    • 2016-05-02
    • 2013-09-09
    • 1970-01-01
    • 2012-08-31
    • 1970-01-01
    相关资源
    最近更新 更多