php - MVC 博客 - 如何包含 header\footer\other.php 文件

标签 php html sql model-view-controller

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

我明白它是如何工作的, router.php 调用合适的页面 Controller 。此 Controller 调用模型,然后使用返回值调用 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,但有 patterns 是基于它的)

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

// class \Application\View\Posts
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();
}

另外, View 实例应该做的事情之一是从模型层请求信息。

一些您可能会觉得有用的 Material :

如果您想扩展 OOP 方面的知识,this post包含推荐讲座和书籍的列表。

关于php - MVC 博客 - 如何包含 header\footer\other.php 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11780858/

相关文章:

php - 更改分页中的序列号

php - Laravel 和 Paypal

PHP 从 URL 中获取 CSV,加载到数组中,格式化

html - 谁能解释为什么元素对齐中心?

sql - 通过某种排序从表中删除前 N 行(按 'Column' 排序)

javascript - Google reCAPTCHA V2 JavaScript 我们检测到您的站点未验证 reCAPTCHA 解决方案

css - 寻找一种更简单的方法来使表格居中并在右侧有边距

html - 如何使 HTML 表格的宽度与其包含的 div 标记相同?

sql - 想要处理一个大的 appengine 日志文件

php - CakePHP 迁移数据库行