PHP5中MVC结构学习


Posted in PHP onOctober 09, 2006

一.介绍

现在在开发WEB应用的时候,比较流行的一种做法就是使用“MVC”结构,使用如此方式去开发WEB应用程序,逻辑性强、简浩明了,使程序设计起来更加方便,快捷。何为“MVC”呢?简单的来说,它就是“模型(Model)”、“视图(View)”及“控制器(Controller)”的结合体,也就是所有的“三层”抽象结构,当然这里所说的“MVC”是针对WEB上应用而言的,“使代码和页面设计分开”便是其主导思想,这一思想在使用Java Servlet/JavaServer Pages技术的“Struts”中表现的淋漓尽致,有兴趣的可以去http://jakarta.apache.org/struts看看,这种设计模式使的程序设计人员可以专注于代码的设计、编写及调试,网页设计人员可以有更多的时间去投入设计而不用理会具体的功能实现,这种分工方式完全适应大型项目或企业级的分布式应用开发。

从PHP5的推出可以看到,其中的面向对象功能越来越完善,使用PHP来开发大型的商业网站或者分布式企业应用已经成为可能,如果再结合Zend Optimizer,已经实现了代码的封装性。

如何在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"在当前程序目录下
包含文件请看"example8"

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@hnwj.net}
[/tplCode]
第二种用法:
[tplCode]
{email:redhat@hnwj.net,Redhat的邮箱}
[/tplCode]
第三种用法:
[tplCode]
{email:redhat@hnwj.net,这是"Redhat"的邮箱<-dh->这个是带样式的<-dh->class=m,m}
[/tplCode]
具体使用请参考"example5"

10.在模板中定义变量
[tplCode]
{assign:$tplVar,这是我定义的变量<-dh->可以在模板中输出也可用PHP代码输出}
[/tplCode]
具体使用请参考"example6".

11.其它语法及功能尚在开发中......
有好的意见或想法请去http://2002.buyionline.net/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,保存在当前目录下,即"./"),内容如下:
<?php
require_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的值就显的很重要。可以像这样使用此方法"$ttt->setQuery("typeid=$tid&msgid=$sid")",这里要注意当恶意用户提交不同的$tid或$sid时也会导致上述的攻击事件,所以必须在程序中捕捉到非法的$tid和$sid并停止执行"$ttt->display()"方法。

assign(String,String|array)
设置在模板中要用到的变量,第一个参数为模板中要用到的变量,第二个参数为用户定义的值,如下:
$obj->assign('webName','主页名字');
$obj->assign('userID',array(23,37,12,18));

display(String|null)
输出解析后的模板,参数为要输出的模板文件名(如果在类的初始化或使用了方法"setTplFile()"已经设置过,在使用本方法时可以不用带参数)

PHP 相关文章推荐
php一些公用函数的集合
Mar 27 PHP
php操作mysql数据库的基本类代码
Feb 25 PHP
PHP+jQuery 注册模块开发详解
Oct 14 PHP
利用PHP函数计算中英文字符串长度的方法
Nov 11 PHP
php按字符无乱码截取中文的方法
Mar 27 PHP
php把大写命名转换成下划线分割命名
Apr 27 PHP
php根据日期显示所在星座的方法
Jul 13 PHP
在WordPress中获取数据库字段内容和添加主题设置菜单
Jan 11 PHP
php使用正则验证中文
Apr 06 PHP
php写app接口并返回json数据的实例(分享)
May 20 PHP
详解PHP中的 input属性(隐藏 只读 限制)
Aug 14 PHP
PHP闭包定义与使用简单示例
Apr 13 PHP
PHP5/ZendEngine2的改进
Oct 09 #PHP
PHP模板引擎SMARTY
Oct 09 #PHP
PHP入门速成(2)
Oct 09 #PHP
用PHP制作静态网站的模板框架
Oct 09 #PHP
PHP5在Apache下的两种模式的安装
Sep 05 #PHP
WINDOWS 2000下使用ISAPI方式安装PHP
Sep 05 #PHP
教你IIS6的PHP最佳配置方法
Sep 05 #PHP
You might like
php与XML、XSLT、Mysql的结合运用实现代码
2009/11/19 PHP
php常用Stream函数集介绍
2013/06/24 PHP
Linux下php5.4启动脚本
2014/08/03 PHP
推荐一款PHP+jQuery制作的列表分页的功能模块
2014/10/14 PHP
php中header跳转使用include包含解决参数丢失问题
2015/05/08 PHP
php实现图片上传并进行替换操作
2016/03/15 PHP
ExtJS 工具栏 分页事件参数
2010/03/05 Javascript
javascript判断iphone/android手机横竖屏模式的函数
2011/12/20 Javascript
浅析javascript 定时器
2014/12/23 Javascript
jQuery实现仿QQ在线客服效果的滚动层代码
2015/10/15 Javascript
表单验证正则表达式实例代码详解
2015/11/09 Javascript
ES6的新特性概览
2016/03/10 Javascript
AngularJs Managing Service Dependencies详解
2016/09/02 Javascript
jQuery实现的多张图无缝滚动效果【测试可用】
2016/09/12 Javascript
微信小程序图片横向左右滑动案例
2017/05/19 Javascript
基于JavaScript实现选项卡效果
2017/07/21 Javascript
微信小程序wx.previewImage预览图片实例详解
2017/12/07 Javascript
JavaScript+H5实现微信摇一摇功能
2018/05/23 Javascript
Node.js操作系统OS模块用法分析
2019/01/04 Javascript
Jquery遍历筛选数组的几种方法和遍历解析json对象,Map()方法详解以及数组中查询某值是否存在
2019/01/18 jQuery
vue 实现移动端键盘搜索事件监听
2019/11/06 Javascript
使用TS来编写express服务器的方法步骤
2020/10/29 Javascript
探究数组排序提升Python程序的循环的运行效率的原因
2015/04/01 Python
详解Python中with语句的用法
2015/04/15 Python
Python中使用Beautiful Soup库的超详细教程
2015/04/30 Python
Python制作爬虫采集小说
2015/10/25 Python
浅谈python中的面向对象和类的基本语法
2016/06/13 Python
利用django-suit模板添加自定义的菜单、页面及设置访问权限
2018/07/13 Python
python pyinstaller 加载ui路径方法
2019/06/10 Python
Django中自定义admin Xadmin的实现代码
2019/08/09 Python
python 协程 gevent原理与用法分析
2019/11/22 Python
python数据处理——对pandas进行数据变频或插值实例
2020/04/22 Python
在python里使用await关键字来等另外一个协程的实例
2020/05/04 Python
2016公司新年问候语
2015/11/11 职场文书
SQL语句中JOIN的用法场景分析
2021/07/25 SQL Server
Win11电源已接通但未充电怎么办?Win11电源已接通未充电的解决方法
2022/04/05 数码科技