2014-06-15 17 views
1

我正在创建自己的原始MVC(或某些人可能称之为的MVP)框架,我想知道包含页眉,页脚和其他任何内容的最佳实践方式在我的控制器中。在控制器中包含标题,菜单和页脚

目前我正在做它像在控制器结束了以下内容:

class Index extends Controller 
{ 
    public function index() 
    { 
     $hData = array(
      'title'  => 'Home', 
      'stylesheets' => array(
       'style1.css', 
       'style2.css' 
      ), 
      'javascripts' => array(
       'script1.js', 
       'script2.js' 
      ) 
     ); 

     $cData = array(
      'heading' => 'My first PHP application', 
      'message' => 'Hello, world!' 
     ); 

     //HTML Output 
     $header = new View('/views/header.php'); 
     $html = $header->fetch($hData); 

     $menu = new View('/views/menu.php'); 
     $html .= $header->fetch(); 

     $content = new View('/views/index.php'); 
     $html .= $content->fetch($cData); 

     $footer = new View('/views/footer.php'); 
     $html .= $footer->fetch(); 

     echo $html; 
    } 
} 

我是不是做正确或是否有这样做的更好的办法?如果是这样,我会高度赞赏一个例子。

+1

imo,'控制器'更像是'经理'。它要求其他人'用适当的页眉和页脚展示东西',而不是自己做。它需要知道在哪种情况下需要调用哪个“视图”。 '观点'和'模型'决定内容。 –

+0

我认为没有项目规范就很难回答这个问题。如果您正在为1.000.000个用户构建应用程序,那么当您为100个用户构建应用程序时,您将有其他需求。根据我的经验,我可以告诉你,如果你正在构建一个巨大的应用程序,你需要一个更复杂的框架。除了框架体系结构问题之外,我想给你建议看看SPA。海事组织这是未来。 AngularJS是一个很好的框架。如果你想编写你自己的SPA框架,请确保你有足够的JS知识(mem泄漏) – GuyT

回答

1

一般来说,建立自己的MVC框架,将迫使您接受一些妥协。但这里是我的想法:

  1. 你应该有一些模板引擎(理想情况下,可能可替换)。它可以是PHP或者一些已经存在的(Twig,Smarty)

  2. 控制器应该只知道模板引擎将呈现的特定视图。因此,视图应该可以通过名称而不是通过模板文件的具体路径来获得。

  3. 模板引擎应该知道如何将模板名称解析为真实的模板文件。

  4. 模板引擎应该能够接受模板的变量,可以从控制器传递给它。包括页眉,页脚等,应该被你的模板引擎或你的模板所考虑,但不在你的控制器中。例如,您的代码可能支持显示一些内部html的AJAX调用。在这种情况下,模板的名称可以相同,但根据从控制器传递的某个var,模板引擎(或模板本身)可以显示正常请求的页眉和页脚,并省略它们以用于Ajax请求。

  5. 当然,控制器的任务不是以硬编码的方式定义要在模板中加载哪些css文件。但是,可能是是一些可以在控制器中读取的系统设置,然后作为变量传递给模板。

2和3是可选的,如果您不需要额外的灵活性,或者你很肯定,你不会需要在以后切换到Smarty的或嫩枝。

0

你是否考虑过创建一个带有两个参数并将其包裹的printView方法?如果你真的想要没有理由,你需要指定脚本,如果他们不会改变。例如:

class Controller { 

    // Protected makes it visible to children, but not to callers 
    protected function printHTML($bodyPage, $bodyData = array(), $altHeaders = array()){ 
     $defaultHeaders = array(
      'title'  => 'Home', 
      'stylesheets' => array(
       'style1.css', 
       'style2.css' 
      ), 
      'javascripts' => array(
       'script1.js', 
       'script2.js' 
      ) 
     ); 
     $trueHeaders = array_merge_recursive($defaultHeaders, $altHeaders); 

     $header = new View('/views/header.php'); 
     $html = $header->fetch($trueHeaders); 

     $menu = new View('/views/menu.php'); 
     $html .= $header->fetch(); 

     $content = new View($bodyPage); 
     $html .= $content->fetch($bodyData); 

     $footer = new View('/views/footer.php'); 
     $html .= $footer->fetch(); 

     echo $html; 
    } 
} 

class Index extends Controller { 
    public function index() { 
     $this->printHTML(
      '/views/index.php', 
      array(
       'heading' => 'My first PHP application', 
       'message' => 'Hello, world!' 
      ), 
      array(
       'title' => 'My Index Page', 
       'stylesheets' => array(
        'style3.css'// Will use styles 1, 2 and 3 because we merge the array recursively. 
       ) 
      ) 
     ); 
    } 
} 
+0

每个控制器的脚本和样式表可以不同。 –

+0

@KidDiamond这就是为什么你只包含常量的东西(jQuery和一个基本的布局或什么的),每个页面然后可以定义它自己的列表添加,如它可以覆盖标题。 – scragar

0

创建一个名为布局文件夹,将一个名为头文件和页脚文件命名,并把所有的标签,直到你的内容的div,然后要求从View.php视图文件后的header.php,然后把你的footer.php和要求在文件之后关闭所有标签。我就是这么做的。

1

MVC是专门为分离功能而设计的。

模型 - 将此视为您的应用程序层。当你设计你的模型时,它就是应用程序本身。你需要什么内容?这通常以原始形式返回。数组,对象,JSon等

查看 - 视图是如何为数据提供服务的。 PHP是一个很好的模板引擎,但也有其他的,如SmartyTwig,它们基于PHP,专门为模板而设计。看看他们,看看你的想法。我个人使用Smarty,并且正在研究Symfony(一种使用Twig查看视图的MVC框架)以实现潜在的未来项目。但是很多人说PHP本身就很好。每个人都有优点和缺点。

控制器 - 控制器告诉程序该做什么以及该去哪里。这是您的业务逻辑层。您的前部控制器位于您的模型和视图之间,以便将正确的内容放入正确的位置。

因此,在考虑页眉和页脚时,请考虑它们属于哪里。最后,因为这是一个模板和图像的问题,它可能最适合在View中使用。

编辑:视图

如果您选择使用PHP作为模板,你可以从非常基本的(难以扩展)走一路从头一个高度动态的面向对象的模板引擎的实例。根据您的项目范围,我将再次强烈建议您至少在Smarty或Twig上选择作为选项。

简单的模板:用户配置文件 模板可以如此简单:

<?php include("header.html.php"); 
/*I am using .html because you can also create .xml views. 
     The beauty of MVC is you can create multiple views with 
     the same model, just having your controller direct 
     to the correct view. */ ?> 
<!-- Your content here --> 
    <div id="userPicture"><img src="<?php echo $userPictureLocation; ?>"></div> 
    <div id="userDetails"> 
     <div id="userName"> 
      <span class="key">Name:</span> 
      <span class="value"><?php echo $userNameValue; ?></span> 
     </div> 
     <div id="userBio"> 
      <span class="key">Bio:</span> 
      <span class="value"><?php echo $userBioValue; ?></span> 
     </div> 
    </div> 
<!-- End Content --> 
<?php include ("footer.html.php"); ?> 

使用这个非常简单的和难以维护的模板系统,你可以简单地在前端控制器使用include $file;

如果你想创建一个面向对象的视图,而不是像Smarty或Twig那样使用模板引擎,那么你将会创建你自己的对象类。你或许可以看看Smarty和/或Twig的功能,以了解需要什么。它正在重塑车轮,但重新发明车轮是一个很好的学习工具。然而,你可以做的一件非常简单的事情是添加一个具有功能setValue(),getValue()load()的模板类。 load()setValue()可以在您的模板中使用,并且getValue()可以在您的模板中使用。

class template { 
    private $values; 

    public function __construct() { 
     $this->values = array(); 
    } 

    public function setValue($key, $value) { 
     $this->values[$key] = $value; 
    } 

    public function getValue($key) { 
     return $this->values[$key]; 
    } 

    public function load($file) { 
     //The APPLOCATION constant below would be under a configuration 
     //file define('APPLOCATION','/var/www/html/'); or whatever your app location 
     //is. A Registry Class is probably a better bet for a large application and is 
     //the best practices way to do it. 
     include APPLOCATION . "template/{$file}"; 
    } 
} 

这个类是非常轻量级的,但也可以添加到。它可以防止一些更加恶意的复制,并且可以通过有限的努力进行扩展。

因此,我们再次使用Template对象查看之前的模板。

<?php 
//In this example I am assuming you declared a new Template 
//in your Controller and assigned it the value of $template. 
$template->load("header.html.php"); 
?> 
<!-- Your content here --> 
    <div id="userPicture"><img src="<?php echo $template->getValue('userPictureLocation'); ?>"></div> 
    <div id="userDetails"> 
     <div id="userName"> 
      <span class="key">Name:</span> 
      <span class="value"><?php echo $template->value('userNameValue'); ?></span> 
     </div> 
     <div id="userBio"> 
      <span class="key">Bio:</span> 
      <span class="value"><?php echo $template->value('userBioValue'); ?></span> 
     </div> 
    </div> 
<!-- End Content --> 
<?php $template->load("footer.html.php"); ?> 
+0

你可以提供一个在你的答案中描述的视图的例子吗? –

+0

我用一个例子更新了我的问题。 – smcjones