MVC博客-如何包含页眉页脚other.php文件



遵循本教程http://johnsquibb.com/tutorials/mvc-framework-in-1-hour-part-one我正在尝试写我的第一个MVC博客

我了解它的工作原理,router.php调用合适的页面控制器。此控制器调用模型,然后用返回的值调用View页面。

我的问题是,如果我想在同一个news.php页面上添加页眉\页脚,该怎么办。通常我会写"include"("header.php")。但现在使用MVC时,我该如何实现呢?

这些是我的文件:

router.php:

    <?php
/**
 * This controller routes all incoming requests to the appropriate controller
 */
//Automatically includes files containing classes that are called
//fetch the passed request
$pageURL = $_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"];
$path_parts = pathinfo($pageURL);
$page_name = $path_parts['filename']; 
$parsed = explode('?' , $page_name);
//the page is the first element
$page = array_shift($parsed);
// If there is any variables, GET them.
if(!empty($parsed))
{
    $parsed = explode('&' , $parsed[0]);
    $getVars = array();
    foreach ($parsed as $argument)
    {
        //explode GET vars along '=' symbol to separate variable, values
        list($variable , $value) = explode('=' , $argument);
        $getVars[$variable] = urldecode($value);
    }
}
//compute the path to the suitable file
$target ='controllers/' . $page . '_controller.php';
//get target controller
if (file_exists($target))
{
    include_once($target);
    //modify page to fit naming convention
    $class = ucfirst($page) . '_Controller';
    //instantiate the appropriate class
    if (class_exists($class))
    {
        $controller = new $class;
    }
    else
    {
        //did we name our class correctly?
        die('class does not exist!');
    }
}
else
{
    //can't find the file in 'controllers'! 
    die('page does not exist!');
}
//once we have the controller instantiated, execute the default function
//pass any GET varaibles to the main method
$controller->main($getVars);

//  AutoLoad
function __autoload($className)
{        
    // Parse out filename where class should be located
    // This supports names like 'Example_Model' as well as 'Example_Two_Model'
    list($suffix, $filename) = preg_split('/_/', strrev($className), 2);
    $filename = strrev($filename);
    $suffix = strrev($suffix);
    //select the folder where class should be located based on suffix
    switch (strtolower($suffix))
    {    
        case 'model':
            $folder = '/models/';
            $filename = ($className);
        break;
        case 'library':
            $folder = '/libraries/';
        break;
        case 'driver':
            $folder = '/libraries/drivers/';
        break;
    }
    //compose file name
    $file = SERVER_ROOT . $folder . strtolower($filename) . '.php';
    //fetch file
    if (file_exists($file))
    {
        //get file
        include_once($file);        
    }
    else
    {
        //file does not exist!
        die("File '$filename' containing class '$className' not found in
'$folder'.");    
    }
}
?>

post_controller.php

<?php
    /**
     * This file handles the retrieval and serving of posts posts
     */
    class Posts_Controller
    {
        /**
         * This template variable will hold the 'view' portion of our MVC for this 
         * controller
         */
        public $template = 'posts';
        /**
         * This is the default function that will be called by router.php
         * 
         * @param array $getVars the GET variables posted to index.php
         */
        public function main(array $getVars)
        {
            //$b_controller =new  Bottom_Bar_Controller;
            //$b_controller->main($getVars);
            $postsModel = new Posts_Model;
            //get an post
            $post = $postsModel->get_post($getVars['id']);
            //create a new view and pass it our template
            $header = new View_Model('header_template');
            $bottom_bar = new View_Model('bottom_bar');
            $view = new View_Model($this->template);

            //assign post data to view
            $view->assign('header', $header->render(FALSE));
            $view->assign('bottom', $bottom_bar->render(FALSE));
            $view->assign('title' , $post['title']);
            $view->assign('content' , $post['content']);
            $view->assign('date' , $post['date']);
            $view->assign('by' , $post['added_by']);
            $view->render();
        }
    }

posts_model.php

<?php
/**
 * The Posts Model does the back-end heavy lifting for the Posts Controller
 */
class Posts_Model
{
    /**
     * Holds instance of database connection
     */
    private $db;
    public function __construct()
    {
        $this->db = new MysqlImproved_Driver;
    }
    /**
     * Fetches article based on supplied name
     * 
     * @param string $author
     * 
     * @return array $article
     */
    public function get_post($id)
    {        
        //connect to database
        $this->db->connect();
        //sanitize data
        $author = $this->db->escape($id);
        //prepare query
        $this->db->prepare
        (
            "
            SELECT *  FROM `posts`
            WHERE
                `id` = '$id'
            LIMIT 1
            ;
            "
        );
        //execute query
        $this->db->query();
        $article = $this->db->fetch('array');
        return $article;
    }
}
?>

view_model.php

<?php
/**
 * Handles the view functionality of our MVC framework
 */
class View_Model
{
    /**
     * Holds variables assigned to template
     */
    private $data = array();
    /**
     * Holds render status of view.
     */
    private $render = FALSE;
    /**
     * Accept a template to load
     */

    public function __construct($template)
    {
        //compose file name
        $file = SERVER_ROOT . '/views/' . strtolower($template) . '.php';

        if (file_exists($file))
        {
            /**
             * trigger render to include file when this model is destroyed
             * if we render it now, we wouldn't be able to assign variables
             * to the view!
             */
            $this->render = $file;

        }        
    }
    /**
     * Receives assignments from controller and stores in local data array
     * 
     * @param $variable
     * @param $value
     */
    public function assign($variable , $value)
    {
        $this->data[$variable] = $value;
    }
    /**
     * Render the output directly to the page, or optionally, return the
     * generated output to caller.
     * 
     * @param $direct_output Set to any non-TRUE value to have the 
     * output returned rather than displayed directly.
     */
    public function render($direct_output = TRUE)
    {
        // Turn output buffering on, capturing all output
        if ($direct_output !== TRUE)
        {
            ob_start();
        }
        // Parse data variables into local variables
        $data = $this->data;
        // Get template
        include($this->render);
        // Get the contents of the buffer and return it
        if ($direct_output !== TRUE)
        {
            return ob_get_clean();
        }
    }
    public function __destruct()
    {
    }
}

posts.php

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link href="../style/style.css" rel="stylesheet" type="text/css" media="screen" />  
<title> Posts (View)</title>
</head>
<body>
       <div id="main">
        <div class="container">
        <?=$data['header'];?>
            <div id="content">  
                <div class="content-background">
                <h2> <?=$data['title'];?></h2>
                <h4> <?=$data['date'];?> </h4>
                <p><?=$data['content'];?></p>
                </div>
            </div>
         </div>
        </div>

    </body>
</html>

问题的一部分是,您的教程对MVC启发的设计模式有一个相当原始的解释(您实际上无法在PHP中实现经典MVC,但有一些模式是基于它的)

视图不仅仅是一个模板。视图应该是类实例,它包含所有的表示逻辑并处理多个模板。您实际拥有的是一个包含posts模板的layout模板。

// class ApplicationViewPosts
public function render()
{
    $layout = new Template( $this->defaultTemplateDirectory . 'layout.html');
    $content = new Template( $this->defaultTemplateDirectory . 'posts.html' );
    $layout->assign( 'content' , $content->render() );
    return $layout->render();
}

此外,视图实例应该做的一件事是从模型层请求信息。

你可能会发现有用的材料很少:

  • 模型-视图混淆第1部分:为什么MVC中的视图访问模型
  • 简单PHP模板引擎
  • MVC中应该如何构建模型

如果你想扩展OOP的知识,这篇文章包含了一系列推荐的讲座和书籍。

MVC结构中没有很好的解决方案。您可以在每个框架中找到解决方案。例如,在CakePHP中,您可以使用AppController,它总是为每个请求调用。有点像基本控制器。

但不,做得不太好。

最简单的方法是直接从视图中询问数据。这听起来很奇怪,但在MVC结构中是可以接受的。因此,在您的视图中,您可以调用$News->getLatestItems(10);并与他们合作。

我不喜欢它,但它很管用。

如果你有很多小部件和块,单独的MVC可能不是正确的结构。然后你可以看看以下内容:http://techportal.inviqa.com/2010/02/22/scaling-web-applications-with-hmvc/它是MVC的衍生物。

您看到的另一个解决方案越来越多:通过AJAX调用请求它。因此,只需在页面加载后加载它们。这样也可以解决问题,因为一个MVC请求会变成多个MVC请求。

最新更新