下面就要开始实现 控制器-模型-视图

我们的思路是这样的,建立一个核心模型和核心控制器,在以后自己的模型和控制器中来继承核心模型和控制器,核心模型和控制器中主要可以是一些通用的方法和必须的组建的加载,下面我们先来写核心控制器,新建system/core/controller.php

<?php
/**
 * 核心控制器
 * @copyright   Copyright(c) 2011
 * @author      yuansir <yuansir@live.cn/yuanxuxu.com&gt;
 * @version     1.0
 */
class Controller{

        public function __construct() {
               // header('Content-type:text/html;chartset=utf-8');
        }
        /**
         * 实例化模型
         * @access      final   protected
         * @param       string  $model  模型名称
         */
        final protected function model($model) {
                if (empty($model)) {
                        trigger_error('不能实例化空模型');
                }
                $model_name = $model . 'Model';
                return new $model_name;
        }
        /**
         * 加载类库
         * @param string $lib   类库名称
         * @param Bool  $my     如果FALSE默认加载系统自动加载的类库,如果为TRUE则加载非自动加载类库
         * @return object
         */
        final protected function load($lib,$auto = TRUE){
                if(empty($lib)){
                        trigger_error('加载类库名不能为空');
                }elseif($auto === TRUE){
                        return Application::$_lib[$lib];
                }elseif($auto === FALSE){
                        return  Application::newLib($lib);
                }
        }
        /**
         * 加载系统配置,默认为系统配置 $CONFIG['system'][$config]
         * @access      final   protected
         * @param       string  $config 配置名
         */
        final   protected function config($config){
                return Application::$_config[$config];
        }
        /**
         * 加载模板文件
         * @access      final   protect
         * @param       string  $path   模板路径
         * @return      string  模板字符串
         */
        final protected function showTemplate($path,$data = array()){
                $template =  $this->load('template');
                $template->init($path,$data);
                $template->outPut();
        }
}

注释都写的很清楚了吧,其实很简单,这里的加载模板的方法中 load 了一个系统自动加载的模板类,这个类我们在建立视图的时候再来讲,然后我们再来建核心模型的文件system/core/model.php

<?php
/**
 * 核心模型类
 * @copyright   Copyright(c) 2011
 * @author      yuansir <yuansir@live.cn/yuanxuxu.com&gt;
 * @version     1.0
 */
class Model {
        protected $db = null;

        final public function __construct() {
                header('Content-type:text/html;chartset=utf-8');
                $this->db = $this->load('mysql');
                $config_db = $this->config('db');
                $this->db->init(
                        $config_db['db_host'],
                        $config_db['db_user'],
                        $config_db['db_password'],
                        $config_db['db_database'],
                        $config_db['db_conn'],
                        $config_db['db_charset']
                        );                                            //初始话数据库类
        }
        /**
         * 根据表前缀获取表名
         * @access      final   protected
         * @param       string  $table_name    表名
         */
        final protected function table($table_name){
                $config_db = $this->config('db');
                return $config_db['db_table_prefix'].$table_name;
        }
        /**
         * 加载类库
         * @param string $lib   类库名称
         * @param Bool  $my     如果FALSE默认加载系统自动加载的类库,如果为TRUE则加载自定义类库
         * @return type
         */
        final protected function load($lib,$my = FALSE){
                if(empty($lib)){
                        trigger_error('加载类库名不能为空');
                }elseif($my === FALSE){
                        return Application::$_lib[$lib];
                }elseif($my === TRUE){
                        return  Application::newLib($lib);
                }
        }
        /**
         * 加载系统配置,默认为系统配置 $CONFIG['system'][$config]
         * @access      final   protected
         * @param       string  $config 配置名
         */
        final   protected function config($config=''){
                return Application::$_config[$config];
        }
}

因为模型基本是处理数据库的相关内容,所以我们加载了 mysql 类,这个 mysql 类就不在这里写了,你可以自己根据习惯写自己的 mysql 的操作类,如果你想支持其他的数据库,完全可以自己灵活添加。

核心模型控制器已经有了,其实里面还可以添加其他你觉得必要的全局函数,这样我们开始新建一个自己的控制器和模型,来实例运用一下新建controller/testController.php

<?php
/**
 * 测试控制器
 * @copyright   Copyright(c) 2011
 * @author      yuansir <yuansir@live.cn/yuanxuxu.com&gt;
 * @version     1.0
 */
class testController extends Controller {

        public function __construct() {
                parent::__construct();
        }

        public function index() {
                echo 'test';
        }

        public function testDb() {
                $modTest = $this->model('test');        //示例化test模型
                $databases = $modTest->testDatebases(); //调用test模型中 testDatebases()方法
                var_dump($databases);
        }
}

testController 继承我们的核心控制器,其实在以后的每个控制器中都要继承的,现在我们通过浏览器访问 http://localhost/myap/index.php?controller=test ,哈哈,可以输出 “test” 字符串了,然后我们再新建一个模型 model/testModel.php

<?php
/**
 * 测试模型
 * @copyright   Copyright(c) 2011
 * @author      yuansir <yuansir@live.cn/yuanxuxu.com&gt;
 * @version     1.0
 */
class testModel extends Model{

        function testDatabases(){
                $this->db->show_databases();
        }
}

其实就是定义了一个获取所有的数据库的方法,打开浏览器访问 http://localhost/myapp/index.php?controller=test&action=testDb,不管你信不信,反正我的浏览器是输出了所有的数据库了

现在就差视图了,其实在核心控制器的 controller.php 文件中已经有了一个showTemplate方法,其实就是实现了加载模板类,$data 就是我们要传递给模板的变量,然后输出模板

        /**
         * 加载模板文件
         * @access      final   protect
         * @param       string  $path   模板路径
         * @param       array   $data   模板变量
         * @return      string  模板字符串
         */
        final protected function showTemplate($path,$data = array()){
                $template =  $this->load('template');
                $template->init($path,$data);
                $template->outPut();
        }

下面我们来看一下 template 类

<?php
/**
 * 模板类
 * @copyright   Copyright(c) 2011
 * @author      yuansir <yuansir@live.cn/yuanxuxu.com>
 * @version     1.0
 */
final class Template {
        public $template_name = null;
        public $data = array();
        public $out_put = null;

        public function init($template_name,$data = array()) {
                $this->template_name = $template_name;
                $this->data = $data;
                $this->fetch();
        }
        /**
         * 加载模板文件
         * @access      public
         * @param       string  $file
         */
        public function fetch() {
                $view_file = VIEW_PATH . '/' . $this->template_name . '.php';
                if (file_exists($view_file)) {
                        extract($this->data);
                        ob_start();
                        include $view_file;
                        $content = ob_get_contents();
                        ob_end_clean();
                        $this->out_put =  $content;
                } else {
                        trigger_error('加载 ' . $view_file . ' 模板不存在');
                }
        }
        /**
         * 输出模板
         * @access      public
         * @return      string
         */
        public function outPut(){
                echo $this->out_put;
        }

是不是简单,就是引入你的静态模版文件,放在缓冲区,然后输出,其实如果你想静态化某个模版,那个这个放在缓冲区的$this->out_put 就有用了,你可以在里面添加一个静态化的方法。 好了,现在我们来在新建一个视图文件 view/test.php

<html>
  <body>
    这是<?php echo $test; ?>,呵呵
  </body>
<html>

然后修改一些我们的 testController.php 中的 index()

        public function index() {
                $data['test'] = 'yuanxuxu.com';
                $this->showTemplate('test', $data);
        }

再来浏览 http://localhost/myapp/index.php?controller=test ,可以输出 “这是 yuanxuxu.com,呵呵”,那么显然我们的视图也完成了。

这样我们的自己写 PHP 的 MVC 的框架就完成了,再补充一下,有人可能疑惑如果我是想建立前台后台的,单一入口怎么办呢,其实你要是从头就看我的这个教程,看下代码就会发现,其实只要在 controller 目录下新建一个 admin 目录就可以在里面写控制器了,比如controller/admin/testController.php 模板引用也是同样的道理,建立 view/admin/test.php ,然后模板加上路径就可以了,

$this->showTemplate(‘admin/test’, $data);是不是很简单,很灵活。

好了,这样我们《自己动手写 PHP MVC 框架》的教程就结束了,你可以模仿自己写一个,也可以根据自己的思路来写一个,我教程中的可以自己扩增成一个完善的框架,再次申明一下,教程中的代码不完善,没有做过任何基准测试,效率神马的不考虑,便捷性神马的看个人,呵呵,如果需要源码的朋友请留下邮箱!

下载 自己动手写 PHP MVC 框架教程源码

转载请注明: 转载自Ryan 是菜鸟 | LNMP 技术栈笔记

如果觉得本篇文章对您十分有益,何不 打赏一下

谢谢打赏

本文链接地址: 自己动手写 PHP MVC 框架(三)

知识共享许可协议 本作品采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可