MVC框架,see again

前言

写这篇文章的初衷,是因为群里因为一个美女工程师而引发了一阵骚动,作为一个看到美女就眼睛放光的人来说,怎么会放过这么好欣赏美女的机会[色]。于是大家将美女的github给翻出来了,我有幸看到了美女写的php框架,download下来,认真向美女学习[崇拜ing]。

美女的框架前言是这样:

写此框架的初衷是因为发现现在流行的php框架都异常臃肿,臃肿的原因是因为框架都封装了许多的功能,这些功能我在实际开发中很多并未使用到,这就造成使用框架的性能浪费。

基于此,于2014年的五一期间写了这个框架,众多流行框架都有一个自己的名字,我就为这个框架取名叫“one”。

刚开始参加工作的时候,因为技术基础很烂,所以被分配到去做管理平台的网页。那时候被同事问及知道什么是MVC吗,我说听过,不知道确切的MVC是什么。于是同事介绍哪里写哪一部分,哪里负责什么功能,什么部分该写在什么部分。第一次就是简单在index.html添加一个菜单,通过这个菜单跳转到某一个页面。

此框架虽然简单,但是其提取出来了核心骨架,虽然不适合真正去建立大型网站,但是适合初学者去了解MVC以及网站的基本搭建。

代码范例

一个美女的简单的PHP框架one---- https://github.com/linsunny/one

想要鉴定美女的童鞋,可以发挥自己的想象力网上百度下。

代码架构

框架的架构如下图所示,library文件夹保存的是核心类,也就是一些基类,比如model,view,controller的基类,mysql的sql操作类,启动框架逻辑,统筹全局的core类。index.php作为入口文件,view存储的主要为视图文件,如html,或者是smarty的tpl文件,st为静态文件,比如js,css,image等。model保存的是业务逻辑处理代码文件,负责处理用户请求,保存用户数据到db,cache,以及访问db,cache读取用户数据等。controller保存的是负责接收用户请求,并调用model处理用户请求,并将用户请求结果在view中显示。配置文件保存的是各种资源(db,smarty,router等)的相关配置。

  

后续会在代码中体现这些文件是如何各司其责的。

本部分将通过分析在浏览器输入一个url链接到页面显示的整个过程,了解本框架的数据流。

在本机上部署好xmapp环境后,将代码放到/var/www/html/目录下

url: http://beauty/one-branch/index.php?c=index&a=init

在浏览器中输入如上链接,点击enter,可以看到如下的页面。

附上页面显示

数据流

  • 域名解析服务器ip和port

  如在浏览器中输入网址:http://beauty/one-branch/index.php?c=index&a=init

  • 通过web服务器找到相应的代码路径

  http解析上面的网址,域名beauty解析到服务器172.16.0.0:80,然后在172.16.0.0这台服务器上的apache的配置文件(如下截图所示)将根据port,找到根目录路径DocumentRoot。即将http://beauty映射到172.16.0.0的目录/var/www/html下,从而将

http://beauty/one-branch/index.php?c=index&a=init    映射到   var/www/html/one-branch/index.php?c=index&a=init

配置文件的截图如下:

附上apache配置 

index.php的代码如下:

<?php

define(‘ROOT_PATH‘, dirname(__FILE__) . DIRECTORY_SEPARATOR );
define(‘CONTROLLER_PATH‘, ROOT_PATH . ‘controller‘ . DIRECTORY_SEPARATOR);
define("VIEW_PATH", ROOT_PATH ."view" . DIRECTORY_SEPARATOR);
define("CACHE_PATH", ROOT_PATH ."cache" . DIRECTORY_SEPARATOR);
define("MODEL_PATH", ROOT_PATH ."model" . DIRECTORY_SEPARATOR);
define("CONFIG_PATH", ROOT_PATH ."config" . DIRECTORY_SEPARATOR);
define("LIBRARY_PATH", ROOT_PATH ."library" . DIRECTORY_SEPARATOR);
define("ST_PATH", ROOT_PATH ."st" . DIRECTORY_SEPARATOR);

include CONFIG_PATH . "config.php";
include LIBRARY_PATH . "core.php";

Core::run($config);  // main函数,入口函数

在index.php中除了定义一些全局宏变量,包含配置文件和核心类文件。只有一句运行代码,调用了核心类Core的run函数。

我们看看框架启动入口主函数Core::run($config)函数主要干啥子了?!

    /**
     * 框架启动逻辑
     *
     */
    public static function run($config) {
        //获取配置文件
        self::$_config = $config;

        //获取路由信息
        $router = self::_parseUrl();

        //自动加载核心类
        self::autoLoad();

        //调用控制器及其方法
        self::initController($router);
    }

1. 获取配置文件

  config配置主要配置:

  • Controller的路由信息
  • Model中需要的db和redis信息
  • View中的模版引擎的相关信息
<?php
/**
 * config.php
 *
 * 此配置文件在框架载入中就已经加载
 *
 * @author linsunny<[email protected]>
 */

/**
 * 路由配置信息
 * $config[router][‘show‘][1] = xx.com/index.php?c=controller&a=action
 * $config[router][‘show‘][2] = xx.com/index.php/controller/action
 */
$config[‘router‘]  = array(
    ‘default_controller‘    =>    ‘index‘,
    ‘default_action‘        =>    ‘init‘,
    ‘show‘                    =>    2,
);
/**
 * 模板引擎配置信息
 * $config[‘smarty‘][‘suffix‘]表示模板文件的后缀名
 * $config[‘smarty‘][‘isCache‘]表示是否用缓存 (默认不启动)
 * $config[‘smarty‘][‘cacheLeftTime‘]表示缓存有效期 (默认保存3600秒)
 */
$config[‘smarty‘] = array(
    ‘template_dir‘    =>    VIEW_PATH,
    ‘compile_dir‘    =>    CACHE_PATH . "compile" . DIRECTORY_SEPARATOR,
    ‘cache_dir‘    =>    CACHE_PATH . "cache" . DIRECTORY_SEPARATOR,
    ‘suffix‘        =>    ".htm",
    ‘isCache‘        =>    true,
    ‘cacheLeftTime‘    =>    3600,
);

/**
 *数据库配置
 *$config[‘db‘][‘conn‘]表示数据库连接标识; pconn 为长久链接,默认为即时链接
 */
$config[‘db‘] = array(
    ‘host‘           =>      ‘localhost‘,
    ‘user‘           =>      ‘root‘,
    ‘password‘       =>      ‘‘,
    ‘database‘       =>      ‘idou‘,
    ‘table_prefix‘   =>      ‘v1_‘,
    ‘charset‘        =>      ‘urf8‘,
    ‘conn‘           =>      ‘‘,
    ‘port‘             =>         80
);

2.  解析Url获取路由信息

解析参数找到相应的Controller类以及该类的运行函数,以及函数参数

运行这个脚本 var/www/html/one-branch/index.php,然后解析后面?c=index&a=init带的参数,第一个参数以?分割,后续以&分割。

获取c的参数c=index,a=init.

3. 自动加载核心类

加载之前core文件夹中的核心类(model,view,controller,mysql),将这些代码路径require或者include进来。

4. 调用控制器及其方法

c标识controller, 故该类是indexController,c=index,a=init说明在Controller模块中找到indexController类,并且运行该类的indexController::init函数。

    /**
     * 初始化控制器
     * 调用对应控制器以及方法
     * @class Core
     */
    public static function initController($router) {
        static $codeAr = array();//定义静态变量储存数组,类似单例模式,这里用来存储控制方法逻辑
        $key = $router[‘c‘] . "_" . $router[‘a‘];

        $controller = $router[‘c‘] . "Controller";
        $action = $router[‘a‘] . "Action";

        //加载控制器文件
        $controller_path = CONTROLLER_PATH . $controller . ".php";
        self::loadFile($controller_path);

        //创建控制器
        $object = new $controller();
        if(method_exists($object, $action)){
            $codeAr[$key] = $object->$action();
        }else{
            self::error("控制器方法不存在!");
        }
        return $codeAr[$key];
    }

接下来调用相应的indexController中的init函数。在init函数中先调用model函数读写db获得相应数据,再将相应数据assign给view,最后将view渲染display。

附上indexController的代码

/**
     * 页面显示
     * 传入模板文件名,返回编译文件路径
     * @access public
     * @return string
     */
    public function display($file) {
        if(!$file) Core::error( ‘参数错误‘ );
        $view_file = self::$config[‘template_dir‘] . $file;
        if( !file_exists($view_file) ) Core::error( $view_file . ‘模板文件不存在‘ );
        $cache_file = self::$config[‘cache_dir‘] . md5($file);
        //当缓存文件存在且不过期时直接从缓存文件读取内容
        if( $this->checkCacheExpire($cache_file, self::$config[‘cacheLeftTime‘]) ){
            echo $this->readFile($cache_file);
        }else {
            extract($this->var);//注册key=value

            $view_content = $this->readFile($view_file);//读文件
            $view_content = $this->replaceTag($view_content);//替换标签

            $temp_file = self::$config[‘compile_dir‘] . md5($file).‘.htm.php‘;
            $this->writeFile($temp_file, $view_content);

            ob_start();
            include($temp_file);
            $content = ob_get_contents();
            ob_end_clean() ;
            if (self::$config[‘isCache‘]){
                $this->writeFile($cache_file,$content) ;//编译好的内容写入缓存文件
            }
            echo $content ;
        }
    }

 

之后附上本程序的流程图,以及本程序的日志文件。

后记

再此附上一张鸟哥的框架流程图。

也有人说框架应该叫做MVCD,D指的是Data,附上MVCD的一张图,说清楚1,2,3,4这几个步骤。

参考资料:

http://www.laruence.com/manual

https://github.com/linsunny/one

Question:

url链接除了可以带c和a参数以外,还可以带其他参数作为action函数的参数,所以parseUrl和initController的函数都还可以进行扩展。

可以扩展通过model读取到数据,然后赋值给view中的参数显示出来。

时间: 2024-10-21 09:03:29

MVC框架,see again的相关文章

使用Intellij Idea自定义MVC框架

今天我学习了自定义一个简单的MVC框架,这个我们首先要知道什么是MVC框架! MVC框架: MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑.数据.界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑.MVC被独特的发展起来用于映射传统的输入.处理和输出功能在一个逻辑的图形化用户界面的结构中. 我们今天自己定义的

Java MVC框架性能比较

- by zvane 现在各种MVC框架很多,各框架的优缺点网络上也有很多的参考文章,但介绍各框架性能方面差别的文章却不多,本人在项目开发中,感觉到采用了struts2框架的项目访问速度,明显不如原来采用了struts1框架的项目快,带着这些疑惑,我对各类MVC框架的做了一个简单的性能分析比较,其结果应该说是基本符合预期的,可供大家参考. 测试环境:CPU:酷睿2 T5750,内存:DDR2-667 2G,Web容器:Tomcat6.0,最大线程数设置为1000,操作系统:WinXP-sp3 测

MVC框架中的值提供(一)

在MVC框架中action方法中的Model数据的绑定的来源有很多个,可能是http请求中的get参数或是post提交的表单数据,会是json字符串或是路径中的相关数据;MVC框架中针对这些不同的数据来源抽象了IValueProvider接口; public interface IValueProvider { bool ContainsPrefix(string prefix); ValueProviderResult GetValue(string key); } IValueProvide

搭建基于spring MVC框架 + RESTful架构风格技术总结

实战篇: 在SpringMVC框架中搭建RESTful架构风格来完成客户端与服务器端的低耦合度.可扩展性.高并发与大数据流量的访问. 用RESTful架构的创建步骤: 1.创建一个全新的Web工程 2.导包,导入所需要的所有第三方jar包.(springMVC+Hibernate的基本包是必须的) 3.作配置,针对不同的项目需求和不同的搭建设计,开发人员可以按照自己的编码风格来设计符合项目开发具体 应该用多少篇配置文件.但是这几篇配置文件是必不可少的: 3-1.web.xml配置文件:最基本的配

关于 mvc框架

M model(模型) 处理应用程序数据逻辑的部分,通常模型对象负责在数据库中存取数据. 模型是应用程序的主体部分. 模型代表了业务数据和业务逻辑: 当数据发生改变时,它要负责通知视图部分:一个模型能为多个视图提供数据.由于同一个模型可以被多个视图重用,所以提高了应用的可重用性. V view(视图) 通常视图是依据模型数据创建的.视图是用户看到并与之交互的界面.视图向用户显示相关的数据,并能接收用户的输入数据,但是它并不进行任何实际的业务处理.视图可以向模型查询业务状态,但不能改变模型.视图还

Spring MVC 框架搭建及详解

一.Spring MVC环境搭建:(Spring 2.5.6 + Hibernate 3.2.0) 1. jar包引入 Spring 2.5.6:spring.jar.spring-webmvc.jar.commons-logging.jar.cglib-nodep-2.1_3.jar Hibernate 3.6.8:hibernate3.jar.hibernate-jpa-2.0-api-1.0.1.Final.jar.antlr-2.7.6.jar.commons-collections-3

开发自己的PHP MVC框架(一)

这个教程能够使大家掌握用mvc模式开发php应用的基本概念.此教程分为三个部分.如今这篇是第一部分. 如今市面上有非常多流行的框架供大家使用.可是我们也能够自己动手开发一个mvc框架.採用mvc模式能够大大降低我们开发应用的时间,并且能够更好的组织项目源码,并且当中的某些模块还可在其他项目中使用.如今我要教大家写一个简单的mvc框架.因为这个项目非常easy,轻量.所以可能并非最佳实践,也不具备安全性.还须要大家在实际应用中完好. 所用技术:php,面向对象开发方法. 開始 首先在站点根文件夹下

ASP.NET MVC框架下添加菜单栏及分页项目

原创声明:本文为作者原创,转载请注明出处:http://www.cnblogs.com/DrizzleWorm/p/7274866.html ,谢谢! 我是做前端开发的,之前用C#的三层架构(UI.BLL.DAL)做过一个网站,这是我第一次接触ASP.NET MVC框架,首先给大家分享别人整理的ASP.NET MVC框架的一组教程:http://www.cnblogs.com/powertoolsteam/archive/2015/08/13/4667892.html内容很齐全,我是在先看了其他

8 -- 深入使用Spring -- 7...2 MVC框架与Spring整合的思考

8.7.2 MVC 框架与Spring整合的思考 对于一个基于B/S架构的JAVA EE 应用而言,用户请求总是向MVC框架的控制器请求,而当控制器拦截到用户请求后,必须调用业务逻辑组件来处理用户请求.此时有一个问题:控制器应该如何获得业务逻辑组件? 最容易想到的策略是,直接通过new 关键字创建业务逻辑组件,然后调用业务逻辑组件的方法,根据业务逻辑方法的返回值确定结果. 在实际的应用中,很少见到采用上面的访问策略,因为这是一种非常差的策略.不这样做至少有如下三个原因: ⊙ 控制器直接创建业务逻

030.自定义的MVC框架

.LOG自定义的MVC框架 M: Model模型V: View 视图C: Controller 控制器 ASP.Net 1. Web窗体编程2. Mvc编程 IHttpHandler任何处理web请求的类必须实现此接口void ProcessRequest(HttpContext context)bool IsReuseable{get;} 使用IHttpHandler实现登录与注册1.新建UserHandelr:IHttpHandler接口2.web.config配置,处理 /user.do请