教程:使用PHP开发自己的MVC框架

合集下载

mvc框架 大纲 php

mvc框架 大纲 php

MVC(Model-View-Controller)是一种常见的软件设计模式,被广泛用于构建各种类型的应用程序。

在PHP中,有许多MVC框架可供选择,用于简化应用程序的开发和提高代码的可维护性。

以下是使用PHP MVC框架开发应用程序的基本大纲:1. 模型(Model):模型是应用程序的数据层,负责处理与数据相关的逻辑。

模型与数据库进行交互,执行数据的增删改查等操作。

在MVC框架中,模型是与数据库交互的组件,封装了数据访问逻辑。

2. 视图(View):视图是应用程序的界面层,负责展示数据给用户。

视图通常包含HTML、CSS和JavaScript等前端技术,用于呈现用户界面。

在MVC框架中,视图是与用户交互的组件,负责渲染和显示模型中的数据。

3. 控制器(Controller):控制器是应用程序的控制层,负责接收用户的请求并处理业务逻辑。

控制器接收用户的输入,调用模型进行数据处理,然后将结果传递给视图进行展示。

在MVC框架中,控制器是连接模型和视图的桥梁,负责处理用户请求并协调模型和视图之间的交互。

使用PHP MVC框架开发应用程序的基本步骤如下:1. 确定应用程序的需求和功能:在开始开发之前,需要明确应用程序的需求和功能,以便进行适当的架构设计和模块划分。

2. 选择合适的MVC框架:根据需求和功能选择适合的MVC框架。

一些流行的PHP MVC框架包括Laravel、Symfony、CodeIgniter等。

3. 创建模型:根据业务需求创建模型类,定义数据表和数据操作方法。

4. 创建视图:根据用户界面需求创建视图文件,使用HTML、CSS和JavaScript等技术进行界面设计。

5. 创建控制器:根据用户请求创建控制器类,处理业务逻辑并调用模型和视图进行交互。

6. 路由配置:配置路由规则,将URL路径映射到相应的控制器和操作方法。

7. 测试和调试:对应用程序进行测试和调试,确保功能正常工作并修复潜在的问题。

php实现简单的MVC框架实例

php实现简单的MVC框架实例

php实现简单的MVC框架实例本⽂实例讲述了php实现简单的MVC框架。

分享给⼤家供⼤家参考。

具体如下:在开始之前需要知道的知识1.php基础知识具备以上两点, 那我们就可以开始啦. 哈哈!先来说⼀下程序的执⾏流程⾸先有个⼊⼝⽂件, 然后初始化⼀些程序, 之后根据请求调⽤不同的类和⽅法⾸先我们弄⼀个⼊⼝⽂件 Index.php 来看看代码<?phprequire "Init.php";$control = new Controller();$control->Run();>代码没什么特别的, ⾸先先引⼊Init.php⽂件然后实例化⼀个类然后调⽤该类的Run()⽅法这⾥我们把这个类叫做控制器既然引⼊了Init.php⽂件, 那么我们继续看看Init.php⽂件的源码<?phpheader("Content-type:text/html;charset=utf-8");!defined('ROOT_PATH') && define('ROOT_PATH', str_replace('\\', '/', dirname(__FILE__)));require ROOT_PATH . '/Core/Config.php'; //引⼊配置⽂件require ROOT_PATH . '/Core/Controller.class.php'; //引⼊控制器类⽂件require ROOT_PATH . '/Core/View.class.php'; //视图类⽂件require ROOT_PATH . '/Core/Model.class.php'; //模型类⽂件>分析⼀下代码, 如果你懂了, 可以略过这⼀步, 继续往下看哦.⾸先设置字符集, 然后判断如果没有定义常量"ROOT_PATH"那么就定义它然后就是引⼊⼀些⽂件, ⾸先是配置⽂件, 控制器类⽂件, 视图类⽂件, 模型类⽂件同理既然引⼊了⽂件,那么我们就打开⽂件看看代码, 先来看Config.php⽂件<?php$C = array('URL_MODE' => 1, //URL模式, 1普通模式, 2 PATH_INFO模式'DEFAULT_CONTROL' => 'welcome', //默认调⽤的控制器'DEFAULT_ACTION' => 'index', //默认执⾏的⽅法);>没什么特别的就是⼀个数组, 有三个值, 暂时先这样, 以后有需要在来增加那么好, 我们继续看Controll.class.php<?phpclass Controller{public function Run(){$this->Analysis(); //开始解析URL获得请求的控制器和⽅法$control = $_GET['c'];$action = $_GET['a'];//这⾥构造出控制器⽂件的路径$controlFile = ROOT_PATH . '/Controllers/' . $control . '.class.php';if(!file_exists($controlFile)) //如果⽂件不存在提⽰错误, 否则引⼊{exit('控制器不存在' . $controlFile);}include($controlFile);$class = ucwords($control); //将控制器名称中的每个单词⾸字母⼤写,来当作控制器的类名if(!class_exists($class)) //判断类是否存在, 如果不存在提⽰错误{exit('为定义的控制器类' . $class);}$instance = new $class(); //否则创建实例if(!method_exists($instance, $action)) //判断实例$instance中是否存在$action⽅法, 不存在则提⽰错误{exit('不存在的⽅法' . $action);}$instance->$action();}protected function Analysis(){global $C; //包含全局配置数组, 这个数组是在Config.ph⽂件中定义的if($C['URL_MODE'] == 1) //如果URL模式为1 那么就在GET中获取控制器, 也就是说url地址是这种的http://localhost/index.php?c=控制器&a=⽅法 {$control = !empty($_GET['c']) ? trim($_GET['c']) : '';$action = !empty($_GET['a']) ? trim($_GET['a']) : '';}else if($C['URL_MODE'] == 2) //如果为2 那么就是使⽤PATH_INFO模式, 也就是url地址是这样的 http://localhost/index.php/控制器/⽅法/其他参数 {if(isset($_SERVER['PATH_INFO'])){//$_SERVER['PATH_INFO']URL地址中⽂件名后的路径信息, 不好理解, 来看看例⼦//⽐如你现在的URL是 http://localhost/index.php 那么你的$_SERVER['PATH_INFO']就是空的//但是如果URL是 http://localhost/index.php/abc/123//现在的$_SERVER['PATH_INFO']的值将会是 index.php⽂件名称后的内容 /abc/123/$path = trim($_SERVER['PATH_INFO'], '/');$paths = explode('/', $path);$control = array_shift($paths);$action = array_shift($paths);}}//这⾥判断控制器的值是否为空, 如果是空的使⽤默认的$_GET['c'] = $control = !empty($control) ? $control : $C['DEFAULT_CONTROL'];//和上⾯⼀样$_GET['a'] = $action = !empty($action) ? $action : $C['DEFAULT_ACTION'];}}>注释写的很清楚, 这⾥我就不多说了, 做到这, 你就可以建⽴⼀个Controller⽬录, 然后在⽬录中建⽴welcome.class.php⽂件写⼊如下内容<?phpclass Welcome{public function index(){echo 'Hello';}}>允许程序你将会看到Hello然后在写⼀个⽅法<?phpclass Welcome{public function index(){echo 'Hello';}public function show(){echo '⽅法名称Show';}}>希望本⽂所述对⼤家的php程序设计有所帮助。

php打造属于自己的MVC框架

php打造属于自己的MVC框架

php打造属于自己的MVC框架本篇先介绍一下php的MVC实现原理,我们框架的MVC部分也是基于此原理实现的,但是今天的代码并不是框架内的代码,仅仅为说明原理一、文件结构建立3个文件夹controller文件夹存放控制器文件view文件夹存放视图文件model文件夹存放数据文件建立1个index.php 作为唯一入口二、控制器我们在controller文件夹下建立一个democontroller.php文件,文件内容如下复制代码代码如下:<?phpclass DemoController{function index(){echo('hello world');}}/* End of file democontroller.php */这个文件里面我们只是建立了一个名为DemoController的对象并包含一个index的方法,该方法输出hello world。

下面在index.php中执行DemoController中index方法。

index.php的代码如下复制代码代码如下:<?phprequire('controller/democontroller.php');$controller=new DemoController();$controller->index();/* End of file index.php */运行index.php,ok如愿我们看到了我们久违的hello world。

这两个文件非常简单,但也揭示了一点点m vc的本质,通过唯一入口运行我们要运行的控制器。

当然controller部分应该是由uri来决定的,那么我们来改写一下index.php使他能通过uri来决定运行那个controller。

index.php改写代码如下:复制代码代码如下:<?php$c_str=$_GET['c'];//获取要运行的controller$c_name=$c_str.'Controller';//按照约定url中获取的controller名字不包含Controller,此处补齐。

51CTO学院-PHP打造属于自己的MVC框架实战视频课程

51CTO学院-PHP打造属于自己的MVC框架实战视频课程

51cto学院-PHP打造属于自己的MVC框架实战视频课程课程目标在本课程中你能够学会MVC的基本原理,MVC的路由机制,单例模式,PDO数据库操作类的封装,以及如何架构属于自己的MVC项目。

利用本课所学技能,能够独立搭建项目底层或开发一个小型的PHP框架!适用人群PHP爱好者,具有PHP基础及PHP面向对象相关知识的童鞋。

课程简介本课程重点讲解了当前主流MVC设计模式,以及MVC实际项目中的应用。

包含内容有MVC基本原理、MVC工作流、MVC的URL路由、spl _autoload_register加载类文件、单例模式、PDO方式封装MODEL类等;MVC底层搭建完成后会讲解一个“微吐槽”的项目,最后将讲解如何开发一个“个人博客”项目;通过这两个项目的讲解使你能够深入的理解及掌握MVC设计模式。

项目课程和本课程是独立分开的,请小伙伴们根据需要购买。

课程第一章课程简介1课时6分钟1课程简介[免费观看]6分钟课程所讲内容介绍。

第二章初识MVC2课时7分钟2开发工具介绍3分钟课程所使用的开发工具介绍及常用操作说明。

3什么是MVC?[免费观看]4分钟MVC介绍,MVC基本原理,为什么使用MVC三层架构。

第三章MVC底层框架搭建19课时3小时11分钟4MVC目录结构创建[免费观看]3分钟MVC项目目录结构创建5单一入口[免费观看]2分钟介绍什么是单一入口,单一入口给我们带来的好处等。

6URL路由之pathinfo路由[免费观看]10分钟讲解最熟悉的URL网页传参形式的pathinfo路由的实现及原理。

7隐藏index.php4分钟为什么要隐藏index.php,如何进行隐藏等。

8URL路由之重写URL路由14分钟重写形式URL路由的原理,如何进行实现。

9自动加载类文件10分钟项目会经常命名各种类,如果使用最原始的require或者include则会增加代码的冗余度,本节主要讲解如何注册自己的自动加载类方法。

php运用MVC模式

php运用MVC模式

如何在PHP中使用“MVC”设计模式去开发WEB应用如何在PHP中使用“MVC”设计模式去开发WEB应用呢?记住一点(代码和页面设计分开),用一个简单的例子演示一下,比如要从数据库中查询出会员的资料以显示在网页上,这里就需要考虑到两点:1.连接数据库并取出会员资料,2.把会员资料显示在网页上,连接数据库我们使用一个数据库的类,把它叫做“DB”类吧,这个类此时就扮演了“模型(Model)”的角色,接着我们需要编写一个操作“DB”类的程序以取出数据,这个程序所扮演的角色就是“控制器(Controller)”,它接受客户端“POST”或“PUT”的数据,然后再调用“DB”类以取出数据,把这些数据都存放在“控制器(Controller)”中,最后把数据传递给“视图(View)”并按照一定的排版格式显示出来,从上面的分析可以看出,模板在这里就是扮演了“视图(View)”的角色,当然仅仅一个模板类是不能说成是MVC的,真正的MVC不是这么简单的,具体可以参考一下“JSF”。

“3t”是一个模板类,主要是读取“控制器(Controller)”的数据并进行一些特殊处理,最后通过一些简单的模板语法把数据显示出来,它具有一些什么样的特点呢?解析速度快,可以根据需要选择使用html方式缓存或php方式缓存,当然你也可以不用缓存,同样可以实现快速稳定的WEB应用使用简单、安装操作方便,在数据的读取方面类似著名模板类“SMARTY”,在数据显示方面即类似“PHP的语法”又类似“JavaBeans”可扩展性好,你可以根据需要随时加入你想要的功能,因为它是开源的,在不久的日子里,将支持插件功能伸缩性好,支持最新的PHP5,只要你的PHP版本>=4.0.6即可使用,当然你需要有在服务器操作文件的权限功能强大,支持模板的多级嵌套,数组多级循环等等当然此模板还需完善的地方很多,有待在各种环境测试使用才能不断完善,目前仅在LINUX和WINDOWS 环境下测试通过.二.安装1.解压后应该可以看到如下目录结构:./3tx.x/cmp/ 编译后的文件(请确保此文件夹可读写)./3tx.x/tpl/ 模板文件(模板文件都放在这里,确保此文件夹可读)./3tx.x/che/ 缓存文件存放的文件夹(请确保此文件夹可读写)./3tx.x/ttt/ttt.php 3T模板类文件./3tx.x/ 程序文件(您写的程序都放在这里)2.您的PHP版本不能低于PHP4.0.6,我建议你的PHP版本升级至4.3.0以上,程序的整体性能将得到会大幅度提高3.运行时如出现变量未定义请在程序前加上"error_reporting(7);"函数三.语法模板简单语法说明:一般使用左边大括号"{"和右边大括号"}"作为模板语法的开始和结束,当然也可以使用自定义的分隔符,如使用"["和"]",以下说明以大括号为分隔符进行说明(注;下面的[tplCode]和[/tplCode]中间的代码才是模板语法代码)1.在模板文件中使用PHP代码,如:[tplCode]{php}$i = 3;echo $i;{/php}[/tplCode]请参考"example6"2.在模板中使用foreach循环,如:第一种用法(循环数组$a,相当于PHP中的foreach($a as $k=>$v)....)[/tplCode]{foreach:$a,$k,$v}$v = {$v}<br>{/foreach}[/tplCode]第二种用法(可以设定循环几次,假如数组$a有15个元素,则下面的循环则只取最前面5个) [tplCode]{foreach:$a,$k,$v,5}$v = {$v}<br>{/foreach}[/tplCode]第三种用法(可以设定循环几次,假如数组$a有15个元素,则下面的循环则从第3个元素开始,取到第5个元素结束)[tplCode]{foreach:$a,$k,$v,3,5}$v = {$v}<br>{/foreach}[/tplCode]请参考"example1"和"example3",在"foreach"循环中可以使用多维数组,具体请看"example10"3.在模板中使用IF语句,如:第一种用法[tplCode]{if:$a == "hello"}变量$a的值是"hello"{/if}[/tplCode]第二种用法[tplCode]{if:$a == true}变量$a为真{else}变量$a不为真{/if}[/tplCode]第三种用法[tplCode]{if:$a == 2}变量$a的值为2{elseif:$a == 3}变量$a的值为3{/if}[/tplCode]具体使用请参考"example2"及"example6"4.在模板中包含模板文件,如:{tplCode}{includetpl:head.tpl}{/tplCode}这里包含了模板文件"head.tpl",所包含的模板文件必须在同一个目录下5.在模板中包含PHP文件,如:{tplCode}{includephp:head.php}{/tplCode}这里包含了PHP文件"head.php",文件"head.php"在当前程序目录下包含文件请看""6.在模板中输出时间,如:{tplCode}{date:Y-m-d H:i:s}{/tplCode}后面的"Y-m-d H:i:s"字符串是标准的PHP时间标识,具体使用可以参考PHP手册具体使用请参考"example7"7.在模板中使用数学函数第一种用法,直接输出结果{tplCode}{math:3*2-5}{/tplCode}第二种用法,赋值给指定变量{tplCode}{math:3*2-5,$result}{/tplCode}第三种用法,赋值给指定变量,第三个参数设置是否立即输出,设为"Y"输出,"N"不输出{tplCode}{math:3*2-5,$result,Y}{/tplCode}具体使用请参考"example4"8.在模板中使用FOR循环如下代码所示[tplCode]{for:5,1000,1,$i}{$i}<br>{/for}{/tplCode}参数说明:5:表示从5开始循环1000:表示循环到1000结束1:表示每次循环的增量为1,相当于$n++$i:表示得到每次循环的值(上面的"5","1000","1"之类的常数也可用变量来代替,如:{for:$num,$max,$step,$i},其中的变量是在程序中用"assign()"方法赋值的)也参考如下代码(理解一下):[tplCode]{for:500,30,-2,$i}从500开始循环,每次减2,直到30才结束,当前循环的值是:<b>{$i}</b><br>{/for}{/tplCode}具体使用请参考"example2","example11"9.在模板中使用Email标签第一种用法:[tplCode]{email:redhat@}[/tplCode]第二种用法:[tplCode]{email:redhat@,Redhat的邮箱}[/tplCode]第三种用法:[tplCode]{email:redhat@,这是"Redhat"的邮箱<-dh->这个是带样式的<-dh->class=m,m}[/tplCode]具体使用请参考"example5"10.在模板中定义变量[tplCode]{assign:$tplVar,这是我定义的变量<-dh->可以在模板中输出也可用PHP代码输出}[/tplCode]具体使用请参考"example6".11.其它语法及功能尚在开发中......有好的意见或想法请去/2002/gbook.php提一下吧,发现BUG也请及时留言说明一下,谢谢!注:1.本模板支持多层嵌套的模板或PHP文件,支持多层foreach或for循环2.实际使用技巧在实际使用过程中如果把属性$cmpCheck设置为true则每次运行都会编译PHP程序,否则程序会根据编译后的PHP文件的存在时间长短判断是否要重新编译该属性默值即为true,一般在正在使用中才设为false(可加快速度)设置方法如:$tttObj->setCmpCheck(true);3.本程序最大的缺点就是不能准确的捕捉程序中出现的语法错误信息4.暂不支持缓存功能,如果你有好的想法不妨告诉我:-)5.由于采用的是混编模式编译模板为PHP文件,所以请不要输错了(当然模板是支持大小写一致的写法的,也就是说你写一个{math:38*7}和{MatH:38*7}的效果是一样的),如输入"{foreach:$data,k,$v}"编译将通过,但运行的时候会导致一个语法错误,因为里面的"k"前面少了一个"$"符号.本来已经写好了对每一行进行语法分析捕捉错误的代码,但发现代码达到几百行的时候占用时间比较长,如果代码比较少还可以,但如果较多的话会导致性能的下降.而且PHP本身就有很不错的出错信息提示,后来想想就没有去进行每行代码的分析了.6.不知大家是否注意到,在以上的标识中,参数都是不带引号或双引号的(条件判断语句除外),希望注意哦:-)四.使用1.建立PHP文件(命名为first.php,保存在当前目录下,即"./"),内容如下:<?phprequire_once "./ttt/ttt.php";//引入类文件$ttt = new TTT();//初始化3T模板类的实例$ttt->setTplDir("./tpl/");//需要编译的模板文件存放目录$ttt->setCmpDir("./cmp/");//编译后文件的存放目录$ttt->assign('title','天空的颜色');//设置变量$ttt->assign('content','蓝色,天气不错,万里无云,晴');//设置变量$ttt->assign('foot','欢迎欢迎');//设置变量$ttt->display('first.tpl');//输出?>2.建立tpl文件(命名为"first.tpl",保存在目录"./tpl/"下).内容如下:<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><html><head><META http-equiv="Content-Type" content="text/html; charset=gb2312"><title>{$title}</title></head><body>{$content}<br><br>{$foot}</body></html>3.在浏览器浏览http://domain/path/to/3tvx.x/3t/first.php即可看到结果,当然你先要把PHP的运行环境配置好.4.更多例子请看程序自带的"example"系列...五.类属性(部分)$tplDir:String,"./tpl/"模板文件的目录,需要加载的模板就从此处加载$cmpDir:String,"./cmp/"编译后的PHP文件存放目录$cheDir:String,"./che/"$tplFile:String,""模板文件,所要解析的模板主文件$startLeft:String,"{"模板变量的左边界符号,可以自己通过setLeft(String $s)方法去设置$startRight:String,"}"模板变量的右边界符号,可以自己通过setRight(String $s)方法去设置六.类方法(部分)TTT(String|null)类构造器,可以在此直接设置需要解析的模板,如:$obj->TTT("head.tpl");setLeft(String)设置模板变量"$startLeft"的左边界,该变量默认为"{"setRight(String)设置模板变量"$startRight"的左边界,该变量默认为"{"setTplDir(String)设置模板的存放路径,此方法的同名方法是"setTemplatesFile()"setCmpDir(String)设置模板编译后的存放路径,此方法的同名方法是"setCompilesFile()"setCheFile(String)设置缓存的模板文件目录,此方法的同名方法是"setCachesFile()"setCacheFilter(String|array)当使用了模板的缓存功能时,使用此方法设置的文件将不被缓存处理setWordsFilter(array)设置不宜在网站上显示的字符或字符串,如:$ttt->setWordsFilter('abc','xyz');,把网页中的所有"abc"替换成"xyz";setWordsFile(String|array)当设置了不宜在网站上显示的字符或字符串时,用此方法设置的文件中的字符或字符串将会不受"setWordsFilter()"方法影响而直接显示setQuery(String)此方法只在使用了模板的缓存功能时才使用,主要是用来设置唯一的一串字符以使缓存文件不会重复,如果没有设置的话模板也会自动获取但会使程序变的不安全,只要不断的向程序GET不同的参数变会一直生成不同的缓存文件,N时间后,我想你服务器的硬盘就没空间了,当然这些只有在你使用了缓存功能并没有使用此方法设置唯一字符串所造成的,所以正确设置并在程序中处理一些GET或POST的值就显的很重要。

基于MVC模式的PHP框架设计

基于MVC模式的PHP框架设计

基于MVC模式的PHP框架设计【摘要】对于任何语言,框架的发展都是为了降低程序之间的依赖性和耦合性,使重用性达到最高。

本文参照框架、PHP、MVC模型的优缺点,设计一个部署和应用简单、且效率高,具有良好的扩展性和可维护性、占用服务器资源低的PHP框架。

【关键词】框架;MVC模式;PHP本文设计的PHP框架(下文统称为IdeaPHP),是一个采用面向对象的设计思想,基于MVC模式开发的轻量级PHP框架,具有单一入口、类自动加载、强大基础类、扩展类等功能。

该框架继承PHP的优点,部署和应用极为简单、且效率高,具有良好的扩展性和可维护性、占用服务器资源低等特点,能使WEB 开发变得更简单、更快捷,可以稳定的用于个人或中小型企业系统的开发。

1 框架特点1)基于MVC的开发模式,三个部件相互独立,改变其中一个不会影响其它两个,低耦合性;同时,具有很好的维护性、重用性和适用性。

2)本框架采用模块和操作的方式设计,代码采用面向对象思想,框架源码简单易用,独立灵活,便于维护和调试,或二次开发。

3)该框架提供了数据库访问层、功能扩展接口(支持自定义扩展类库和扩展函数),直接使用即可完成一些常见的功能,操作灵活,简单易用。

4)使用Memcached对SQL和session进行缓存,使用Smarty缓存技术进行页面静态化,提升效率,减少运行消耗。

2 框架主要功能2.1 单一入口单一入口即一个文件处理所有的HTTP请求,即访问网站任何功能,都是从浏览器访问index.php文件,这个文件就是这个应用程序的单一入口。

在一般的web过程化编程时,每个PHP文件都能独立访问并运行,这犹如一场演唱会,需要在每个入口都要检票和安全检查。

而采用单一入口进行项目部署和访问时,一个项目只有一个(但不一定是唯一)入口,就像演唱会如果只能从一个入口入场(程序是抽象的,一个和多个入口效率一样),则可以灵活控制现场秩序和安全。

这在一些常见框架如zend,thinkphp,qeephp等,都采用了统一的入口,这样的设计模式在权限控制,url重写,结合MVC清晰的目录结构等都有很大优势。

基于PHP的MVC框架核心技术研究与实现

基于PHP的MVC框架核心技术研究与实现
图 2所 示 。
对 于提高 P H P在 企 业 级应 用 软 件 开 发 中 的 规 范 性 、 可 靠 性 与 可 扩 展 性 都 有 较 大 的促 进 作 用 。
2 MV C实际模 型
MV C( Mo d e l 、V i e w、C o n t r o l l e r ) 是 指 现 代 程 序 设 计 中 一 种 分 层 设 计 模 式 ,将 程 序 代 码 按 其 功 能 边 界 分 为 模 型 ,视 图
S 0 F r W A R E D E V E பைடு நூலகம் 0 P M E N T A N D D E S I G N
软件 开发 与设计
基于 P H P的 MV C框 架核 心技术研 究与实现
罗维
( 成都中医药大学医学信 息工程学 院,成都 6 1 0 0 8 3 )
摘 要 :M V C应用程序开发框架是 MV C开发模 式实现 的基础 。通过对 MV C模 式的深入研 究,以 P H P为基 础 ,提 出了 MV C的 实际模 型 ,设计 了 M V C框 架的体 系架构 ,解决 了框 架的路 由模式 ,研制 了控 制器工厂 、D A O组件与
Ab s t r a c t : MVC a p p l i c a t i o n r f a me wo r k i S f u n d a me n t a l f o r t l l e r e li a z a t i o n MVC d e s i g n p a t t e r n . By t h e t h o r o u g h s t u d y o f t h e t h e o r y o f MVC ,t h i s p a p e r p r o p o s e d a p r a c t i c a l MVC mo d e l b a s e o n P HP l a n g u a g e . T h e a r c h i t e c t u r e o f MVC f r a me w o r k w a s d e s i g n e d .T he ou r t i n g mo d e o f f r a me wo r k w a s r e s o l v e d .T he c o n t r o l l e r f a c t o y ,DAO r c o mp o n e n t a n d t e mp l a t e e n g i n e we r e d e v e l o p e d . F i n a l l y a c o mp l e t e MVC f r a me w o r k d e v e l o p me n t me t h o d wa s f o r me d a s w e l l a s p r o v i d e d s u p p o r t i n g s y s t e m f o r e n t e r p i r s e a p p i f c a t i o n s y s t e m. Ke y wo r d s : MVC mo d e; MVC f r a me wo r k; Ro u t e mo d e; DAO C o mp o n e n t; T e mp l a t e e n g i n e

PHP开发一个属于自己MVC框架

PHP开发一个属于自己MVC框架

PHP开发一个属于自己MVC框架一、起名:先给我们的PHP-MVC框架起个名字,叫宇宙无敌框架UniverseInvincibleFrameWork二、实现功能1、MVC分层2、唯一入口3、关键常量可配置4、自动载入函数5、路由分发6、数据库工厂7、多数据支持8、多项目支持三、详细分解如何PHP-MVC框架1、MVC分层1)、目录结构2)、目录简介(1)、Home、Admin是项目名,可以无限扩展(2)、Config是配置文件所在目录,UniverseInvincibleFrameWork是框架核心文件所在目录(3)、Index.php是唯一入口文件(4)、Home目录下就是标准的Controller、Model、View,另外新增了Service(5)、UniverseInvincibleFrameWork目录下是核心框架入口类、自动载入类、路由类已经数据库文件所在的DB目录(6)、DB目录是数据库相关操作。

比如数据库工厂类,接口规范类,CURD操作等。

2、唯一入口1)、采用单一入口模式进行项目部署和访问,无论完成什么功能,一个项目都有一个统一的入口。

2)、只需要引入框架核心文件App.php,然后执行该类的方法<?php/*** 宇宙无敌框架UniverseInvincibleFrameWork* 唯一入口* Created by lixuan-it@* User: lane* Date: 15/8/27* Time: 下午3:17* E-mail: lixuan868686@* WebSite: *///引入框架核心文件require_once 'UniverseInvincibleFrameWork/App.php'; //初始化框架$obj = new UniverseInvincibleFrameWork\App(); $obj->init();3)、框架核心文件源码:<?phpnamespace UniverseInvincibleFrameWork;class App{public function init(){//设置头- utf-8$this->_setHeader();//载入系统配置文件$this->_loadSysFile();//自动载入函数$this->_setAutoload();//设置路由$this->_setRoute();}/*** 载入系统配置文件*/private function _loadSysFile(){require_once dirname(__FILE__).'/Function.php';//1、require_once dirname(__FILE__).'/../config/config.php';//2、$GLOBALS['config'] =config.php的所有内容$GLOBALS['config'] = require_once dirname(__FILE__).'/../config/config.php'; }/*** 头*/private function _setHeader(){header('Content-type: text/html; charset=UTF-8');}/*** 自动载入函数*/private function _setAutoload(){//自动载入函数require_once dirname(__FILE__).'/../UniverseInvincibleFrameWork/Autoload.php';$autoload = new Autoload();$autoload->register();}/*** 设置路由*/private function _setRoute(){$routeObj = new Route();$routeObj->parse();}}3、关键常量可配置1)、谁也不会傻呼呼的到把数据库链接信息等配置信息写死到代码里,那么就必须有一个配置文件。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

教程:使用PHP开发自己的MVC框架一、什么是MVCMVC模式(Model-View-Controller)是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model)、视图(View)和控制器(Controller)。

MVC模式的目的是实现一种动态的程序设计,使后续对程序的修改和扩展简化,并且使程序某一部分的重复利用成为可能。

除此之外,此模式通过对复杂度的简化,使程序结构更加直观。

软件系统通过对自身基本部份分离的同时也赋予了各个基本部分应有的功能。

专业人员可以通过自身的专长分组:∙(控制器Controller)- 负责转发请求,对请求进行处理。

∙(视图View)–界面设计人员进行图形界面设计。

∙(模型Model)–程序员编写程序应有的功能(实现算法等等)、数据库专家进行数据管理和数据库设计(可以实现具体的功能)。

模型(Model)“数据模型”(Model)用于封装与应用程序的业务逻辑相关的数据以及对数据的处理方法。

“模型”有对数据直接访问的权力,例如对数据库的访问。

“模型”不依赖“视图”和“控制器”,也就是说,模型不关心它会被如何显示或是如何被操作。

但是模型中数据的变化一般会通过一种刷新机制被公布。

为了实现这种机制,那些用于监视此模型的视图必须事先在此模型上注册,从而,视图可以了解在数据模型上发生的改变。

视图(View)视图层能够实现数据有目的的显示(理论上,这不是必需的)。

在视图中一般没有程序上的逻辑。

为了实现视图上的刷新功能,视图需要访问它监视的数据模型(Model),因此应该事先在被它监视的数据那里注册。

控制器(Controller)控制器起到不同层面间的组织作用,用于控制应用程序的流程。

它处理事件并作出响应。

“事件”包括用户的行为和数据模型上的改变。

二、为什么要自己开发MVC框架网络上有大量优秀的MVC框架可供使用,本教程并不是为了开发一个全面的、终极的MVC框架解决方案,而是将它看作是一个很好的从内部学习PHP的机会,在此过程中,你将学习面向对象编程和设计模式,并学习到开放中的一些注意事项。

更重要的是,你可以完全控制你的框架,并将你的想法融入到你开发的框架中。

虽然不一定是做好的,但是你可以按照你的方式去开发功能和模块。

三、开始开发自己的MVC框架在开始开发前,让我们先来把项目建立好,假设我们建立的项目为todo,那么接下来的第一步就是把目录结构先设置好。

虽然在这个教程中不会使用到上面的所有的目录,但是为了以后程序的可拓展性,在一开始就把程序目录设置好使非常必要的。

下面就具体说说每个目录的作用:∙application –存放程序代码∙config –存放程序配置或数据库配置∙db –用来存放数据库备份内容∙library –存放框架代码∙public –存放静态文件∙scripts –存放命令行工具∙tmp –存放临时数据在目录设置好以后,我们接下来就要来顶一下一些代码的规范:1.MySQL的表名需小写并采用复数形式,如items,cars2.模块名(Models)需首字母大写,并采用单数模式,如Item,Car3.控制器(Controllers)需首字母大写,采用复数形式并在名称中添加“Controller”,如ItemsController, CarsController4.视图(Views)采用复数形式,并在后面添加行为作为文件,如:items/view.php,cars/buy.php1 2 3 4 5 &lt;IfModule mod_rewrite.c&gt; RewriteEngine on RewriteRule ^$ public/ [L] RewriteRule (.*) public/$1 [L] &lt;/IfModule&gt;1 2 3 4 5 6 7 8 9 &lt;IfModule mod_rewrite.c&gt;RewriteEngine On#如果文件存在就直接访问目录不进行RewriteRule RewriteCond %{REQUEST_FILENAME} !-f#如果目录存在就直接访问目录不进行RewriteRule RewriteCond %{REQUEST_FILENAME} !-d#将所有其他URL重写到index.php/URL RewriteRule ^(.*)$ index.php?url=$1 [PT,L]&lt;/IfModule&gt;这么做的主要原因有:1.可以使程序有一个单一的入口,将所有除静态程序以外的程序都重定向到index.php上;2.可以用来生成利于SEO的URL,想要更好的配置URL,后期可能会需要URL路由,这里先不做介绍了。

1 2 3 4 5 &lt;?phpdefine('DS',DIRECTORY_SEPARATOR);define('ROOT',dirname(dirname(__FILE__)));$url = $_GET['url'];require_once(ROOT.DS.'library'.DS.'bootstrap.php');注意上面的PHP代码中,并没有添加PHP结束符号”?>”,这么做的主要原因是:对于只包含PHP代码的文件,结束标志(“?>”)最好不存在,PHP自身并不需要结束符号,不添加结束符号可以很大程度上防止末尾被添加额外的注入内容,让程序更加安全。

在index.php中,我们对library文件夹下的bootstrap.php发起了请求,那么bootstrap.php这个启动文件中到底会包含哪些内容呢?1 2 3 &lt;?phprequire_once(ROOT.DS.'config'.DS .'config.php');require_once(ROOT.DS.'library'.DS .'shared.php');1 2 3 4 5 6 7 8 &lt;?php# 设置是否为开发状态define('DEVELOPMENT_ENVIRONMENT',true);# 设置数据库连接所需数据define('DB_HOST','localhost');define('DB_NAME','todo');define('DB_USER','root');define('DB_PASSWORD','root');1 2 3 4 5 6 7 8 9 &lt;?php/* 检查是否为开发环境并设置是否记录错误日志 */function setReporting(){if (DEVELOPMENT_ENVIRONMENT == true) {error_reporting(E_ALL);ini_set('display_errors','On');} else {error_reporting(E_ALL);ini_set('display_errors','Off');1011121314151617181920212223242526272829303132333435363738394041424344454647484950515253 ini_set('log_errors','On');ini_set('error_log',ROOT.DS. 'tmp' .DS. 'logs' .DS. 'error.log');}}/* 检测敏感字符转义(Magic Quotes)并移除他们*/function stripSlashDeep($value){$value = is_array($value) ? array_map('stripSlashDeep',$value) : stripslashes($value);return $value;}function removeMagicQuotes(){if (get_magic_quotes_gpc()) {$_GET = stripSlashDeep($_GET);$_POST = stripSlashDeep($_POST);$_COOKIE = stripSlashDeep($_COOKIE);}}/* 检测全局变量设置(register globals)并移除他们*/function unregisterGlobals(){if (ini_get('register_globals')) {$array = array('_SESSION','_POST','_GET','_COOKIE','_REQUEST','_SERVER','_ENV','_FILES'); foreach ($array as $value) {foreach ($GLOBALS[$value] as $key =&gt; $var) {if ($var === $GLOBALS[$key]) {unset($GLOBALS[$key]);}}}}}/* 主请求方法,主要目的拆分URL请求*/function callHook() {global $url;$urlArray = array();$urlArray = explode("/",$url);$controller = $urlArray[0];array_shift($urlArray);$action = $urlArray[0];array_shift($urlArray);$queryString = $urlArray;$controllerName = $controller;$controller = ucwords($controller);545556575859606162636465666768697071727374757677787980 $model = rtrim($controller, 's');$controller .= 'Controller';$dispatch = new $controller($model,$controllerName,$action);if ((int)method_exists($controller, $action)) {call_user_func_array(array($dispatch,$action),$queryString);} else {/* 生成错误代码*/}}/* 自动加载控制器和模型*/function __autoload($className) {if (file_exists(ROOT . DS . 'library' . DS . strtolower($className) . '.class.php')) {require_once(ROOT . DS . 'library' . DS . strtolower($className) . '.class.php');} else if (file_exists(ROOT . DS . 'application' . DS . 'controllers' . DS . strtolower($className) . '.php')) { require_once(ROOT . DS . 'application' . DS . 'controllers' . DS . strtolower($className) . '.php');} else if (file_exists(ROOT . DS . 'application' . DS . 'models' . DS . strtolower($className) . '.php')) {require_once(ROOT . DS . 'application' . DS . 'models' . DS . strtolower($className) . '.php');} else {/* 生成错误代码*/}}setReporting();removeMagicQuotes();unregisterGlobals();callHook();1 2 3 4 5 6 &lt;?phpclass Controller { protected $_model; protected $_controller; protected $_action; protected $_template;7 8 91011121314151617181920 function __construct($model, $controller,$action) {$this-&gt;_controller = $controller;$this-&gt;_action = $action;$this-&gt;_model = $model;$this-&gt;$model =&amp; new $model;$this-&gt;_template =&amp; new Template($controller,$action); }function set($name,$value) {$this-&gt;_template-&gt;set($name,$value);}function __destruct() {$this-&gt;_template-&gt;render();}}1 2 3 4 5 6 7 8 9101112131415161718 &lt;?phpclass SQLQuery {protected $_dbHandle;protected $_result;/** 连接数据库**/function connect($address, $account, $pwd, $name) {$this-&gt;_dbHandle = @mysql_connect($address, $account, $pwd); if ($this-&gt;_dbHandle != 0) {if (mysql_select_db($name, $this-&gt;_dbHandle)) {return 1;}else {return 0;}}else {return 0;}1920212223242526272829303132333435363738394041424344454647484950515253545556575859606162}/** 中断数据库连接**/function disconnect() {if (@mysql_close($this-&gt;_dbHandle) != 0) {return 1;} else {return 0;}}/** 查询所有数据表内容**/function selectAll() {$query = 'select * from `'.$this-&gt;_table.'`';return $this-&gt;query($query);}/** 查询数据表指定列内容**/function select($id) {$query = 'select * from `'.$this-&gt;_table.'` where `id` = \''.mysql_real_escape_string($id).'\''; return $this-&gt;query($query, 1);}/** 自定义SQL查询语句**/function query($query, $singleResult = 0) {$this-&gt;_result = mysql_query($query, $this-&gt;_dbHandle);if (preg_match("/select/i",$query)) {$result = array();$table = array();$field = array();$tempResults = array();$numOfFields = mysql_num_fields($this-&gt;_result);for ($i = 0; $i &lt; $numOfFields; ++$i) {array_push($table,mysql_field_table($this-&gt;_result, $i));array_push($field,mysql_field_name($this-&gt;_result, $i));}while ($row = mysql_fetch_row($this-&gt;_result)) {for ($i = 0;$i &lt; $numOfFields; ++$i) {$table[$i] = trim(ucfirst($table[$i]),"s");$tempResults[$table[$i]][$field[$i]] = $row[$i];}if ($singleResult == 1) {mysql_free_result($this-&gt;_result);return $tempResults;}array_push($result,$tempResults);}mysql_free_result($this-&gt;_result);63646566676869707172737475767778return($result);}}/** 返回结果集行数**/function getNumRows() {return mysql_num_rows($this-&gt;_result); }/** 释放结果集内存**/function freeResult() {mysql_free_result($this-&gt;_result);}/** 返回MySQL操作错误信息**/ function getError() {return mysql_error($this-&gt;_dbHandle); }}1 2 3 4 5 6 7 8 91011 &lt;?phpclass Model extends SQLQuery{protected $_model;function __construct() {$this-&gt;connect(DB_HOST,DB_USER,DB_PASSWORD,DB_NAME); $this-&gt;_model = get_class($this);$this-&gt;_table = strtolower($this-&gt;_model)."s";}function __destruct() {}}1 2 3 4 &lt;?phpclass Template {protected $variables = array(); protected $_controller;5 6 7 8 91011121314151617181920212223242526272829protected $_action;function __construct($controller,$action) {$this-&gt;_controller = $controller;$this-&gt;_action =$action;}/* 设置变量*/function set($name,$value) {$this-&gt;variables[$name] = $value;}/* 显示模板*/function render() {extract($this-&gt;variables);if (file_exists(ROOT.DS. 'application' .DS. 'views' .DS. $this-&gt;_controller .DS. 'header.php')) { include(ROOT.DS. 'application' .DS. 'views' .DS. $this-&gt;_controller .DS. 'header.php');} else {include(ROOT.DS. 'application' .DS. 'views' .DS. 'header.php');}include (ROOT.DS. 'application' .DS. 'views' .DS. $this-&gt;_controller .DS. $this-&gt;_action . '.php'); if (file_exists(ROOT.DS. 'application' .DS. 'views' .DS. $this-&gt;_controller .DS. 'footer.php')) { include (ROOT.DS. 'application' .DS. 'views' .DS. $this-&gt;_controller .DS. 'footer.php');} else {include (ROOT.DS. 'application' .DS. 'views' .DS. 'footer.php');}}}1 2 3 4 5 6 7 &lt;?phpclass ItemsController extends Controller { function view($id = null,$name = null) {$this-&gt;set('title',$name.' - My Todo List App'); $this-&gt;set('todo',$this-&gt;Item-&gt;select($id)); }function viewall() {8 91011121314151617181920$this-&gt;set('title','All Items - My Todo List App');$this-&gt;set('todo',$this-&gt;Item-&gt;selectAll());}function add() {$todo = $_POST['todo'];$this-&gt;set('title','Success - My Todo List App');$this-&gt;set('todo',$this-&gt;Item-&gt;query('insert into items (item_name) values (\''.mysql_real_escape_string($todo).'\')'));}function delete($id) {$this-&gt;set('title','Success - My Todo List App');$this-&gt;set('todo',$this-&gt;Item-&gt;query('delete from items where id =\''.mysql_real_escape_string($id).'\''));}}1 2 3 &lt;?phpclass Item extends Model { }1 &lt;h2&gt;&lt;?php echo $todo['Item']['item_name']?&gt;&lt;/h2&gt;2 3 4 &lt;a href="../../../items/delete/&lt;?php echo $todo['Item']['id']?&gt;"&gt; &lt;span&gt;Delete this item&lt;/span&gt;&lt;/a&gt;1 2 3 4 5 6 7 8 910111213 &lt;form action="../items/add" method="post"&gt;&lt;input type="text" value="I have to..." onclick="this.value=''" name="todo"&gt; &lt;input type="submit" value="add"&gt;&lt;/form&gt;&lt;br/&gt;&lt;br/&gt;&lt;?php $number = 0?&gt;&lt;?php foreach ($todo as $todoitem):?&gt;&lt;a href="../items/view/&lt;?php echo $todoitem['Item']['id']?&gt;/&lt;?php echo strtolower(str_replace(" ","-",$todoitem['Item']['item_name']))?&gt;"&gt;&lt;span&gt;&lt;?php echo ++$number?&gt;&lt;?php echo $todoitem['Item']['item_name']?&gt;&lt;/span&gt;&lt;/a&gt;&lt;br/&gt;&lt;?php endforeach?&gt;1 &lt;a href="../items/viewall"&gt;Todo successfully added. Click here to go back.&lt;/a&gt;&lt;br/&gt;1 &lt;a href="../../items/viewall"&gt;Todo successfully deleted. Click here to go back.&lt;/a&gt;&lt;br/&gt; header.php:页首文件1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4 &lt;html&gt;&lt;head&gt;&lt;title&gt;&lt;?php echo $title?&gt;&lt;/title&gt;&lt;style&gt;.item {width:400px;}input{color:#222222;font-family:georgia,times;font-size:24px;font-weight:normal;line-height:1.2em;color:black;} a{color:#222222;font-family:georgia,times;font-size:24px;font-weight:normal;line-height:1.2em;color:black;text -decoration:none;}a:hover {background-color:#BCFC3D;}h1{color:#000000;font-size:41px;letter-spacing:-2px;line-height:1em;font-family:helvetica,arial,sans-serif;border-bottom:1px dotted #cccccc;}h2 {color:#000000;font-size:34px;letter-spacing:-2px;line-height:1em;font-family:helvetica,arial,sans-serif;} &lt;/style&gt;&lt;/head&gt;&lt;body&gt;&lt;h1&gt;My Todo-List App&lt;/h1&gt;12&lt;/body&gt;&lt;/html&gt;1 2 3 4 5 CREATE TABLE IF NOT EXISTS `items` (`id` int(11) NOT NULL AUTO_INCREMENT,`item_name` varchar(255) NOT NULL,PRIMARY KEY (`id`)) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=17 ;至此一个使用MVC开发的网站就开发完成了,你现在可以通过访问http://localhost/todo/items/viewall 查看新建的站点。

相关文档
最新文档