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 相关文章推荐
第九节 绑定 [9]
Oct 09 PHP
菜鸟学PHP之Smarty入门
Jan 04 PHP
php的array数组和使用实例简明教程(容易理解)
Mar 20 PHP
php使用session二维数组实例
Nov 06 PHP
php实现excel中rank函数功能的方法
Jan 20 PHP
php安装swoole扩展的方法
Mar 19 PHP
laravel学习教程之关联模型
Jul 30 PHP
详解PHP防止直接访问.php 文件的实现方法
Jul 28 PHP
thinkphp5引入公共部分header、footer的方法详解
Sep 14 PHP
safari下载文件自动加了html后缀问题
Nov 09 PHP
PHP Swoole异步读取、写入文件操作示例
Oct 24 PHP
php 函数中静态变量使用的问题实例分析
Mar 05 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获取服务器端mac和客户端mac的地址支持WIN/LINUX
2014/05/15 PHP
PHP使用CURL实现多线程抓取网页
2015/04/30 PHP
PHP的PDO事务与自动提交
2019/01/24 PHP
Javascript在IE或Firefox下获取鼠标位置的代码
2009/12/18 Javascript
ExtJS下书写动态生成的xml(兼容火狐)
2013/04/02 Javascript
js控制表单操作的常用代码小结
2013/08/15 Javascript
js AppendChild与insertBefore用法详细对比
2013/12/16 Javascript
JavaScript cookie的设置获取删除详解
2014/02/11 Javascript
JS实现弹性漂浮效果的广告代码
2015/09/02 Javascript
js实现左侧网页tab滑动门效果代码
2015/09/06 Javascript
基于JavaScript实现鼠标悬浮弹出跟随鼠标移动的带箭头的信息层
2016/01/18 Javascript
Bootstrap幻灯片轮播图支持触屏左右手势滑动的实现方法
2016/10/13 Javascript
JS常用算法实现代码
2016/11/14 Javascript
微信小程序实现移动端滑动分页效果(ajax)
2017/06/13 Javascript
JavaScript 替换所有匹配内容及正则替换方法
2020/02/12 Javascript
谈谈node.js中的模块系统
2020/09/01 Javascript
解决新建一个vue项目过程中遇到的问题
2020/10/22 Javascript
[57:24]LGD vs VGJ.T 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
Python虚拟环境Virtualenv使用教程
2015/05/18 Python
利用pandas进行大文件计数处理的方法
2018/07/25 Python
python leetcode 字符串相乘实例详解
2018/09/03 Python
python三引号输出方法
2019/02/27 Python
python装饰器简介---这一篇也许就够了(推荐)
2019/04/01 Python
python可视化爬虫界面之天气查询
2019/07/03 Python
Python中list循环遍历删除数据的正确方法
2019/09/02 Python
使用Django搭建一个基金模拟交易系统教程
2019/11/18 Python
python图形开发GUI库pyqt5的详细使用方法及各控件的属性与方法
2020/02/14 Python
Python模拟登入的N种方式(建议收藏)
2020/05/31 Python
如何将json数据转换为python数据
2020/09/04 Python
The Body Shop美体小铺西班牙官网:天然化妆品
2019/06/21 全球购物
日本最大的购物网站:日本乐天市场(Rakuten Ichiba)
2020/11/04 全球购物
护士岗位求职应聘自荐书范文
2014/02/12 职场文书
2014年教研组工作总结
2014/11/26 职场文书
房屋分割离婚协议书范本
2014/12/01 职场文书
Mysql多层子查询示例代码(收藏夹案例)
2022/03/31 MySQL
Apache Hudi的多版本清理服务彻底讲解
2022/03/31 Servers