怎样自己写一个MVC框架
最近想学习php的mvc结构,在网上找了一些资料,可是大部分都是相同的,或者写的不是很满意。接着看了一个cakephp的框架,感觉太多的函数了,让人觉得就是一个记函数的过程,所以觉得不是很好。
我对mvc的理解是:c负责分配任务,协调m和v。用户发出请求时,c把请求分配给模型m,模型从数据库处理查询或者其他的一些数据操作,然后把数据返回给c,c再把数据传递给相应的v,再在前台显示。这有个比喻较好,当我们去餐馆吃饭时,招待×××就相当于c,她把客户的请求传达给厨师m,厨师把做好的菜再给×××,×××把菜再端给顾客。。。。。。。
现在我把自己的做的一个mvc介绍下:
我的访问网址是这种类型:http://www.example.com/index.php?controller/action/id:2/page:3
其中controller是控制器的名字,action是控制器下的动作名称,而action以后的参数,如id:2,page:3等是额外的参数,我们称之为params。
好了,接下来就是怎么解析这个URL,把它分化成controller,action,params。
首先说一下目录结构,
index.php 这是入口文件,用户要访问的每一个页面都要经过它
.htaccess 这是.htaccess文件
app app目录
app/controllers 控制器目录,其中文件名都是nameController的形式,类名和文件名相同,类中的动作名为nameAction的 形式
app/views 视图的目录,这里我借用smarty模板
app/views/cache
app/views/templates 模板文件
app/views/confgs
app/views/templates_c 以上三个目录是与smarty一致的,具体可以参考smarty手册
app/models 模型存放目录
core 核心文件目录
core/ini.php 初始化处理
core/config.php 一些配置文件
core/dbconfig.php 数据库的配置文件
core/dispatcher.php 分发路由
core/router.php URL处理文件
core/loader.php
core/initializer.php 包含一些文件
core/lib
core/lib/appController.php 父控制器
core/lib/appView.php 视图类,主要继承smarty文件
core/lib/appModel.php 父模型类,连接数据库
core/lib/dataAccess.php 数据库的一些基本操作
core/lib/smarty smary的核心文件,完全照搬smarty的libs文件,但将其中的Smarty.class.php重命名为Smarty.php,主要是为了自动化类。
以上就是要用到的目录文件
下面看index.php
//index,php
<?php
include("core/ini.php");
initializer::initialize();
$router = loader::load("router");
dispatcher::dispatch($router);
?>
先慢慢解释。。。。。。。。。。
看ini.php
//ini.php
<?php
header("Content-type:text/html;charset=utf-8");
set_include_path(get_include_path() . PATH_SEPARATOR . "core");
//将要用到的文件包含进来
function __autoload($object){
require_once("{$object}.php");
}
?>
其中__autoload函数很重要,当我们要初期化类时,如果当前文件没有,它就会自动去包含文件中寻找该类。在这里我把类名和文件名设为相同,这比较方便,比如initializer::initialize();此时就会去包含文件中查找initializer.php文件,然后初始化类initializer,再调用它的静态方法initialize();
接着看看initializer.php
//initializer.php
<?php
class initializer
{
public static function initialize() {
set_include_path(get_include_path().PATH_SEPARATOR . "core/lib");
set_include_path(get_include_path().PATH_SEPARATOR . "app/controllers");
set_include_path(get_include_path().PATH_SEPARATOR."app/models");
set_include_path(get_include_path().PATH_SEPARATOR."app/views");
set_include_path(get_include_path().PATH_SEPARATOR."core/lib/smarty");
}
}
?>
这是一个把我们将要用到的文件包含进来,目的是方便我们初始化类方便。
//loader.php
<?php
class loader
{
private static $loaded = array();
public static function load($object){
$valid = array( "library",
"view",
"model",
"helper",
"router",
"config",
"hook",
"cache",
"db");
if (!in_array($object,$valid)){
throw new Exception("Not a valid object '{$object}' to load");
}
if (empty(self::$loaded[$object])){
self::$loaded[$object]= new $object();
}
return self::$loaded[$object];
}
}
?>
//router.php
<?php
class router
{
private $route;
private $controller;
private $action;
private $params;
public function __construct()
{
$path = array_keys($_GET);//取得URL?以后的字符串:controller/action/id:2/page:3
if (!isset($path[0])){
$path[0] = "index";//如果没有控制器名称。则调用index控制器
}
$route= $path[0];
$this->route = $route;
$routeParts =preg_split("",$route);//用“/"划分进数组
$this->controller=$routeParts[0];//控制器名称
$this->action=isset($routeParts[1])? $routeParts[1]:"index";//动作名称,默认是index
array_shift($routeParts);
array_shift($routeParts);
$a=$routeParts;
$b=array();
foreach($a as $aa)
{$c=explode(':',$aa);
$b[$c[0]]=isset($c[1])?$c[1]:$c[0];
}
$this->params=$b;//此时为数组的形式Array ( [id] => 2 [page] => 3 )
}
public function getAction() {
if (empty($this->action)) $this->action="index";
return $this->action;
}
public function getController() {
return $this->controller;
}
public function getParams() {
return $this->params;
}
}
?>
再看看dispatcher.php
//dispatcher.php
<?php
class dispatcher
{
public static function dispatch($router)
{
ob_start();//打开缓冲区
$controller =($router->getController()).'Controller';//控制器类或者控制器的文件名
$action = ($router->getAction()).'Action';//控制器的动作函数名
$params = $router->getParams();
//print_r($params);
$controllerfile = "app/controllers/{$controller}.php";
if (file_exists($controllerfile)){
require_once($controllerfile);
$app = new $controller();//实例化该控制器
$app->params=$params;
$app->$action();//调用该动作函数
$output = ob_get_clean();
echo $output;//输出到浏览器
}else{
throw new Exception("Controller not found");
}
}
}
?>
下面看看index控制器怎么样
//indexController.php
<?php
class indexController extends appController
{
public function indexAction()
{
$this->view->assign('test','hello,world!');
$this->view->display('index.tpl');
}
}
?>
这里有一个appController父类,我们看看它怎么样
//appController.php
<?php
class appController
{
var $model;
var $view;
var $params;
function __construct()
{
$this->model=new appModel();
$this->view=new appView();
}
}
?>
appController主要初始化父类模型和视图,所以接着看看appModel类和appView类是个什么样
//appView.php
<?php
class appView extends Smarty
{
//var $smarty;
function __construct()
{
$this->smarty;
$this->template_dir = 'app/views/templates/';
$this->compile_dir = 'app/views/templates_c/';
$this->config_dir = 'app/views/configs/';
$this->cache_dir = 'app/views/cache/';
}
}
?>
appView主要就是重新包装一下smarty模板
//appModel.php
<?php
require_once('/dbconfig.php');
class appModel extends dataAccess
{
function __construct()
{parent::__construct(DB_HOST,DB_USER,DB_PASSWORD,DB_DATABASE);
}
}
?>
这里负责一些数据库的链接操作,其中dbconfig.php为
//dbconfig.php
<?php
define('DB_HOST','127.0.0.1');
define('DB_USER','root');
define('DB_PASSWORD','min');
define('DB_DATABASE','sdw');
define('CHAR_SET','utf8');
?>
appModel又继承了类文件dataAccess.php,这是数据库处理的一些文件,包括数据库链接,查询等等。。。。。这里就不列出了。
所以现在来看indexController中的动作indexAction中的 $this->view->assign('test','hello,world'); 和$this->view->display('index.tpl');,他们分别是调用父类appController的$this->view类,而$this->view类就是appView类,即smarty类,所以smarty类的assign和display方法应该很熟悉的。
在app/views/templates下建立文件index.tcp
//index.tcp
{$test}
转载于:https://blog.51cto.com/sexy1ei/1043692
怎样自己写一个MVC框架相关推荐
- 自己动手模仿 springmvc 写一个 mvc框架
spring的知识那么多,看源码也不知从何看起,那应该怎么学呢?我觉得,完整的spring我们写不出来,但是一个简单的,我们还是可以实现的.自己动手去实现一个简单的spring,是学习它的最好的方式. ...
- 自己动手写PHP MVC框架
自己动手写PHP MVC框架 来自:yuansir-web.com / yuansir@live.cn 代码下载: https://github.com/yuansir/tiny-php-framew ...
- 从零开始写一个RPC框架的详细步骤
http://blog.csdn.net/liu88010988/article/details/51547592 定位 所谓定位就是回答几个问题,我出于什么目的要写一个框架,我的这个框架是干什么的, ...
- VS 如何创建一个MVC框架
VS 如何创建一个MVC框架 开发工具与关键技术:VS 如何创建一个MVC框架 作者:胡宁淇 撰写时间:2019年1月17日 ASP.NET 是一个使用 HTML.CSS.JavaScript 和服务 ...
- 动手造轮子:写一个日志框架
动手造轮子:写一个日志框架 Intro 日志框架有很多,比如 log4net / nlog / serilog / microsoft.extensions.logging 等,如何在切换日志框架的时 ...
- Day 2---vue2 从0开始 写一个前端框架
项目背景:vue2 业务需求:用Vue+Element 写一个前端框架 今日主线任务:完成静态登陆页面 项目地址: https://gitee.com/whwbs/my_project.git 准备工 ...
- 【RPC框架、RPC框架必会的基本知识、手写一个RPC框架案例、优秀的RPC框架Dubbo、Dubbo和SpringCloud框架比较】
一.RPC框架必会的基本知识 1.1 什么是RPC? RPC(Remote Procedure Call --远程过程调用),它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络的技术. ...
- 学习如何写PHP MVC框架(1) -- 路由
说到PHP开发web,自然离不开开发框架,开发框架为我们提供了灵活的开发方式,MVC层分离,业务解耦等... 第一篇先来简单点的,说说MVC框架的路由功能... 一般的单入口框架路由都是这样的结构: ...
- ssm框架requestmapping找不到_从MVC原理开始手敲一个MVC框架,带你体会当大神的乐趣...
每一个程序员,在刚入行时学的第一个框架应该就是ssm了,其他的各种学习框架都是后期在工作中,随着业务的不断复杂,在工作和bug中不断成长起来的,但是最经典的应该还是最一开始的时候ssm框架吧 当时刚学 ...
最新文章
- 《电子基础与维修工具核心教程》——1.3 弱电、强电、高压电
- Learning To Rank之LambdaMART的前世今生
- mysql 时序 存储引擎_MySQL常见的三种存储引擎
- neo4j查询多跳关系的方法
- 解决Git中fatal: refusing to merge unrelated histories
- EditThisCookie插件的使用方法
- SAP UI5 web Component里的条件渲染机制
- Redis:19---常用功能之(HyperLogLog)
- html校园首页设计说明范文,网页设计作品设计说明-必看请相互转告
- Docker 教程、架构、Linux下的安装
- 学习笔记88—spyder生成的图单独窗口显示
- Hibenate连接mysql错误_hibernate连接数据库问题,注意是表名的大小写
- r语言 悲观剪枝_【R语言新书】前言Ⅲ—R语言编程思想
- Android 应用的启动方式
- 屏幕小于6英寸的手机_6寸手机好不好用 手机屏幕尺寸多大合适
- 一本通 3.1 例 1」黑暗城堡
- typroa 思维导图_巧用Markdown和百度脑图
- 0基础学Java(2)
- codeforces 268E Playlist(数学期望)
- 世界 5G 通信频段和运行模式
热门文章
- C语言第九次博客作业--指针
- UVA - 10061 How many zero#39;s and how many digits ?
- skynet源码阅读5--协程调度模型
- 8.2设备文件及磁盘分区
- myeclipse和maven的clean和build
- uwp应用在debug模式下运行正常,编译为release版本的时候抛出异常
- 14.6.3.1 The InnoDB Buffer Pool
- centos打架django + mysql环境
- SQL:认识数据库约束
- 60个高质量的CSS、XHTML网页布局模板下载