美文网首页WEB-PHPPHPphp
公司目前用的一个 MVC 框架

公司目前用的一个 MVC 框架

作者: 咚门 | 来源:发表于2016-05-25 00:27 被阅读235次

    咚门:时来有空,整理一下公司一直在用的 MVC 框架:

    0. 目录:

    ---- controllers
            --- router.php(路由)
            --- users.php(以其中一个具体的 controller 为例)
            --- ...
    ---- models
            --- view.php(视图类)
            --- users.php(以其中一个具体的 model 为例)
            --- ...
    ---- views
            --- users(以其中一个具体的 view 为例)
                -- index.php
                -- add.php
                -- edit.php
                -- ...
            --- ...
    ---- index.php
    

    1. 入口文件: /index.php

    <?php
    /*
     * index.php是整个web应用的入口点,所有的用户请求都会经过它。
     * 我们会写一些代码来把用户请求分派到相应的控制器中,这些控制器存放在controllers文件夹里
     * 首先在index.php中定义网站根目录和网站域名,以便在整个应用中访问。
     * 定义了网站根目录后,在任何php文件中,都能很方便的引用其它目录的php文件,因为index.php是入口文件,
     * 这样就能够在整个应用中访问在它之中定义的这些变量。
     * 在controllers目录下新建一个文件,名字为“router.php",这个文件用来处理所有页面请求。
     * 想像一下你家里的路由器,它负责把internet路由到家中的每个电脑。
     * router.php文件将会获取传入到index.php的页面请求,然后把请求分派给不同的控制器(controllers)。
     * 创建一个Model(模型)完善News_Controller。
     * 假设我们有一些新闻片段来供读者阅读,那么就需要News_Controller这个控制器去调用一个模型来抓取相关的新闻片段,无论它们是存储在数据库还是文件里。
     * 在models文件夹里新建一个文件,“news.php”
     * 现在我们已经有控制器和模型了,只差一个视图。可以使用原生php视图。在views文件夹里新建一个文件“news.php”
     * 现在我们有了视图文件,但是我们需要一个与视图交互的方法。在models文件夹里新建一个文件“view.php”
     * 访问URL http://域名或IP.com/index.php?news&a=index  news为控制器参数  a=index 为控制器的方法参数
     * 控制器页面可以不用再执行session_start();,数据模型页面和视图页面需要启动 session_start();
    */
    
    session_start();
    header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
    header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
    header("Cache-Control: no-cache, must-revalidate");
    header("Pramga: no-cache");
    ini_set('session.gc_maxlifetime',7200); //设置时间
    set_time_limit(0);
    
    //网站根目录
    define("SITE_ROOT", _DIR_);
    //网站域名
    define('DOMAIN_NAME', 'http://www.ukin.cc');
    //版本常量(此方案不好,导致浏览器每天都要重新下载一次所有资源)
    define("VERSION_TIMESTAMP", date("Ymd"));
    
    //引入PDO文件(哎,虽然这里引入了这个文件,但大家各自为政,在每个model里面自己又再次引入此文件)
    require_once(SITE_ROOT . '/db/' . 'pdo_mysql.php');
    //引入路由控制文件router.php
    require_once(SITE_ROOT . '/controllers/' . 'router.php');
    ?>
    

    2. 路由文件: /controllers/router.php

    <?php
    /*
     * 咚门:__autoload — 尝试加载未定义的类。通过定义这个函数来启用 类的自动加载 。
     *
     * 这个函数重载了PHP内置的autoload函数。当我们试图去初始化一个不存在的类时,这个‘魔术方法’允许我们拦截php所执行的动作。
     * 通过使用__autoload函数,我们能够告诉php寻找包含此类的文件的位置。
     * 假设你遵循了这篇文章中 类和文件名的命名约定 ,那么每当你初始化一个类时,你就不必手动去引入包含此类的文件了!
    */
    
    //当类初始化时,自动引入相关文件(引入数据模型文件)
    function __autoload($className)
    {
        //解析文件名,得到文件的存放路径,如News_Model表示存放在models文件夹里的news.php(这里是作者的命名约定)
        list($filename, $suffix) = explode('_', $className);
    
        //构成 model 文件的路径
        $file = SITE_ROOT . '/models/' . strtolower($filename) . '.php';
    
        //获取文件
        if (file_exists($file)) {
            //引入 model 文件
            include_once($file);
        } else {
            //文件不存在
            die("model 文件【$filename】不存在!");
        }
    }
    
    
    // 获取请求参数(即 URL 参数),例如:http://localhost/index.php?login&a=index
    $request = $_SERVER['QUERY_STRING'];
    
    // 解析请求页面和其它GET变量
    $parsed = explode('&', $request);
    
    // 取得控制器名称:login (array_shift — 将 $parsed 的第一个单元移出并作为结果返回;将 $parsed 的长度减一并将所有其它单元向前移动一位,所有的数字键名将改为从零开始计数,键名将不变。)
    $page = array_shift($parsed);
    
    // 取得:a=index
    $fun_action_a = array_shift($parsed);
    // 取得操作方法名称:index
    $fun_action = str_replace("a=", "", $fun_action_a);
    
    
    /**
     * 此文件会把所有的传入参数分派到相应的控制器中
     */
    
    //检测是否已登录,如果未登录则把控制器和方法重置为登录页面
    require_once(SITE_ROOT . '/public/' . 'check_session.php');
    //$target = SITE_ROOT . '/controllers/' . $page . '.php';
    //echo $fun_action;
    if ($page == "") {
        $page = "login";
        $fun_action = "login";
    }
    
    
    
    //echo $fun_action;
    // 拼接控制器文件的路径
    $target = SITE_ROOT . '/controllers/' . $page . '.php';
    
    if (file_exists($target)) {
    
        // 引入相应的控制器文件
        include_once($target);
    
        // 拼接控制器类名。修改page变量,以符合命名规范(如$page="news",我们的约定是首字母大写,控制器的话就在后面加上“<strong>_Controller”</strong>,即News_Controller)
        $class = ucfirst($page) . '_Controller';
    
        // 初始化对应的控制器类
        if (class_exists($class)) {
            $controller = new $class;
        } else {
            die("控制器类名【$controller】不存在!");
        }
    } else {
        //不能在controllers找到此文件
        die("controller 文件【$page】不存在!");
    }
    
    //初始化控制器后,根据控制器方法参数决定调用的函数(默认调用 index() 函数)
    switch ($fun_action) {
        case "index":
            $controller->index();
            break;
        case "index2":
            $controller->index2();
            break;
        case "index3":
            $controller->index3();
            break;
        case "add":
            $controller->add();
            break;
        case "add2":
            $controller->add2();
            break;
        case "add3":
            $controller->add3();
            break;
        case "add4":
            $controller->add4();
            break;
        case "add5":
            $controller->add5();
            break;
        case "add6":
            $controller->add6();
            break;
        case "add7":
            $controller->add7();
            break;
        case "add8":
            $controller->add8();
            break;
        case "add9":
            $controller->add9();
            break;
        case "edit":
            $controller->edit();
            break;
        case "detail":
            $controller->detail();
            break;
        case "download":
            $controller->download();
            break;
        case "login":
            $controller->login();
            break;
        case "change_password":
            $controller->change_password();
            break;
        case "reset_password":
            $controller->reset_password();
            break;
        default:
            $controller->index();
            break;
    }
    ?>
    

    3. controller 之一: /controllers/users.php

    <?php
    /*
     * 控制器处理页面提交的请求,初始化数据模型,从数据模型获取查询的数据
     * 初始化视图交互方法,调用视图模板
     * 将数据传送到视图模板,在视图页面中显示
    */
    
     class Users_Controller {
    
        // $template变量会保存与此控制器相关的"view(视图)"的文件名,不包括.php后缀
         public $template = 'users';
    
         public function index() {
             //初始化数据模型
             $usersModel = new Users_Model;
    
             //从数据模块获取数据
             $rs_value = $usersModel->index();
    
             //初始化视图交互方法,并传入该控制器的template变量
             $view = new View_Model($this->template,"index");
    
             //把文章数据赋给视图模板
             $view->assign('rs_value' , $rs_value);
        }
    
        public function add() {
            //初始化数据模型
            $usersModel = new Users_Model;
    
            //从数据模块获取数据
            $rs_value = $usersModel->add();
    
            //初始化视图交互方法,并传入该控制器的template变量
            $view = new View_Model($this->template,"add");
    
            //把文章数据赋给视图模板
            $view->assign('rs_value' , $rs_value);
        }
    }
    ?>
    

    4. model 之一: /models/users.php

    <?php
    
    class Users_Model {
    
        public function index() {
            
            // Code
            
            return $rs_value;
        }
    }
    

    5. /models/view.php

    <?php
    /**
     * 在我们的MVC框架中,处理视图的功能
     * 接收控制器传送过来的控制器参数和对应的方法参数,组成视图文件路径
     * 接收控制器赋予的变量,保存在data数组中,传送到视图页面文件中显示
     */
    class View_Model
    {
        // 保存赋给视图模板的变量
        private $data = array();
        public $fun_action;
    
        // 保存视图渲染状态
        private $render = FALSE;
    
        // 加载一个视图模板 $fun_action
        public function __construct($template, $fun_action) {
    
            // 拼接视图文件的路径。$template为控制器传递过来的参数,作为对应视图目录;$fun_action为控制器方法参数,对应该方法的视图
            $file = SITE_ROOT . '/views/' . strtolower($template) . '/' .$fun_action. '.php';
    
            if (file_exists($file)) {
    
                /**
                 * 当模型对象销毁时才能渲染视图
                 * 如果现在就渲染视图,那么我们就不能给视图模板赋予变量
                 * 所以此处先保存要渲染的视图文件路径
                 */
                $this->render = $file;
            }
        }
    
        /**
         * 接受从控制器赋予的变量,并保存在data数组中
         *
         * @param $variable
         * @param $value
         */
        public function assign($variable , $value) {
    
            $this->data[$variable] = $value;
        }
    
        public function __destruct() {
    
            //把类中的data数组变为该函数的局部变量,以方便在视图模板中使用
            $data = $this->data;
    
            //渲染视图
            include($this->render);
        }
    }
    
    ?>
    
    1. 以其中一个具体的 view 为例: /views/users/index.php
    // 就不写具体代码了,
    // 但注意,在 /model/view.php 中把 model 中返回的变量 $rs_value  赋值给了data[$variable],
    // 所以要在 /views/users/index.php 中调用 model 返回的变量,需要用这样的格式:$data['rs_value']['某个具体的变量对应的键名']
    
    1. 其他(与 MVC 无关): /db/pdo_mysql.php
    <?php
        $dbms='mysql';          // 数据库类型 Oracle 用ODI,对于开发者来说,使用不同的数据库,只要改这个,不用记住那么多的函数了(mssql)
        $host='192.168.1.1';    // 数据库主机
        $dbname='test';         // 使用的数据库
        $user='test';           // 数据库用户名
        $pwd='test';            // 数据库密码
        $dsn = "$dbms:host=$host;dbname=$dbname";
        $dbh="";
    
        Try {
            $dbh = new PDO($dsn, $user, $pass); //初始化一个PDO对象,就是创建了数据库连接对象$dbh
            $dbh->exec('SET names utf8');
        } Catch(PDOException $e) {
            // echo 'Error!: ',$e->getMessage(),"\n";
        }
    ?>
    

    相关文章

      网友评论

      本文标题:公司目前用的一个 MVC 框架

      本文链接:https://www.haomeiwen.com/subject/xvzzrttx.html