PHP使用模板引擎 | ||||||||||||||||
一.什么是模板, 使用模板引擎可以使业务逻辑与显示逻辑分开——这是很欠扁但也是网上公认的说法,呃,说得很准确,但估计只有会使用模板的人才能理解„„其实刚开始大可以简单的理解模板为“PHP与HTML代码分离的方法”。 二。为什么要使用模板技术, 让程序(PHP层)与显示(HTML层)分离可以使代码更清晰易懂,要修改程序问题就去PHP层找,要改显示问题就去HTML层改。更重要的是这样 的设计可以让不懂PHP的前台美工也能修改页面。如果不是很理解没关系,你只要知道这是迈向其它高级开发模式的必经之路就可以了。 三。有哪些模板技术, 我使用过PHPLIB库中的模板类,后来又使用了smarty和smartyLight,也试过原生的PHP方式实现的模板,现在大家基本上都用smarty。PHP方式相对来说最容易实现,学得也快,但不适合团队合作。 四。smarty广被攻击的“弱点” smarty的语法太复杂,学它简直就是学一门新语言——其实你不需要复杂的功能,它就简单得很,如果你需要它复杂的功能,那你应该感谢它~根据我的经验,刚开始用一个东西,大家都喜欢简洁精炼,但随着应用的复杂,大多会抱怨它功能不足„„ smarty有几百K,它太大了,慢~——其实大小与速度不成正比,smarty有编译缓存和静态缓存机制,甚至可以局部缓存 另外它的自定义插件用起来非常爽,modify,block等,我这几天正用它的block来输出页面组件。 五。下载,配置smarty 因为我后来一直用smarty的简化版smartyLight,它们的语法大部分相同但也有不同,所以没办法把我现在的代码搬出来以免出错,好吧,为了写这篇,我去下载完整版smarty。 下载2.6.18版的吧,最新的是2008的,不一定很稳定 其它目录都删了,保留libs目录就可以了,如果为了学习可以保留demo目录。 六。实战 使用模板引擎后,PHP代码与模板分离了,一般写一个应用都有PHP和HTML两个页面 PHP部分有三个部分组成:载入与配置、赋值、载入模板解析,其中第一部分是公用的,也就是放到公共页里以后都不需要再写的。第三部分即dispay方法,就一行代码,所以重点在第二部分。 (注:数组都分索引数组和关联数组两种来说明,索引数组即以数字为键的数组,关联数组是每个键有个字符串名称的数组,实在不理解就翻书去) A。普通变量赋值与使用. PHP代码 header(‘Content-Type:text/html;charset=utf-8′); require ‘../libs/Smarty.class.php’; , $smarty = new Smarty; $smarty->compile_check = true; $smarty->debugging = false; //调试时设为true , //以上操作通常在包含页里,也就是说和数据库链接那样的操作类似,写一次就行了,根本不用记 //下面是实际的代码,PHP部分没啥难的,各种类型的变量,数组,对象统统可以用assign方法赋值给模板. $smarty->assign(“name”,“星野天河”); //这句是第二部分。普通的变量 $smarty->display(‘index.tpl’); //载入模板 最后一句的display方法是载入默认模板目录下的index.tpl模板,当然可以修改默认的模板目录。假如要改到abc目录。(不要照抄啊,出错我不负责) PHP代码 $smarty->template_dir = ‘/abc/’; 模板部分(本例为index.tpl文件) XML/HTML代码 普通变量的使用格式: {$name}<br> 这样大括号中的内容会被上面11行定义的name值代替。使用这个你可以把网页标题,关键字,站长名字、图片路径、js路径、网站根目录、文档根等信息都在包含页里直接赋值了(一次性操作),之后在模板里任何地方可以直接使用。路径问题也不至于错乱,修改起来也省事。 B。一维索引数组的赋值与使用 PHP代码 $smarty->assign(“persons”,array(“星野天河”,“小蕊”,“天 空”,“西”,‘奶瓶’)); 将数组丢给$persons变量,html中循环输出数组有两种格式。第一种如下 XML/HTML代码 {section name=item loop=$persons} , {$persons[item]}<br> {/section} section是smarty的循环结构, loop表示要循环哪个变量,这里是$persons这个变量(上面,,,代码中赋值的数组),name表示循环中的每一项值用什么表示,可以随便取名 的,例如叫item,那下面就要用{$persons[item]}表示数组中的一个项。 不过我更习惯使用第二种模式——foreach循环,因为与PHP格式接近,容易理解,并且更重要的是——省代码~效率也高些,记住下面的格式。 XML/HTML代码 {foreach item=person from=$persons} , {$person}<br> {/foreach} 可以理解为把$persons数组拆开,每一项都丢进person变量中,与以下PHP代码完全一样。所以,把section忘了吧。 PHP代码 foreach($persons as $person){ echo $person; } C。一维关联数组 如果是一维相关数组的话,那更简单,不需要使用循环了。 PHP代码 $smarty->assign(“user”,array(‘name’=>“星野天河”,‘iq’=>138, ‘qq’=>15957674)); //一维相关数组的赋值 XML/HTML代码 一维关联数组的使用: {$user.name}: {$user.iq} {$user.qq} 看见了吧,简单透顶,{$user.name}相当于PHP中的{$user['name']},这点和smarty简化版不同(我更喜欢后者的格式{$user[name]} D.二维索引数组 PHP代码
$smarty->assign(“all”, array(array(1,2,3,4,5), array(6,7,8,9,10), array(11,12,13,14,15))); XML/HTML代码 {foreach item=nums from=$all} , {foreach item=num from=$nums} , {$num} {/foreach} <br> {/foreach} 如果对操作PHP数组熟练,很容易理解这种循环镶套,第一轮把$all二维数组中的每一个元素拆到$nums变量中,第二轮再把$nums变量(这里是一维数组了)拆开丢进$num变量中. 二维关联数组的使用 PHP部分 PHP代码 $smarty->assign(“guests”, array( , array(“title” => “第一条留言的标题”, “content” => “第一条标题的内容”, “author” => “留言者小蕊”), array(“title” => “第二条留言”, “content” => “今天带笔了,要签名的排队”, “author” => “星野大叔”)) , ); 实际的应用中,这个二维数组通常是数据库输出结果,所以为了模板使用方便,用db类吧,直接输出数组的那种.赶紧扔了那种 wliel($row=mysql_fetch_assoc($rs)){ //一堆操作 }使用数据库的方式. 回归正题,看一下模板里怎么用二维关联数组吧.这回我不说累赘的section模式了.看foreach XML/HTML代码 {foreach item=guest from=$guests} , {$guest.title}<br> <p>{$guest.content}</p> 留言者:{$guest.author}<br> {/foreach} 应该能够理解,将二维数组中的每一个元素(通常是数据库中的每一条记录)扔进guest变量中,这个变量就是一维相关数组了,使用方式与一维相关数组完全相同. F.三维,四维„„ 二维及其以上的数组都分不清是索引还是关联数组了,很可能是混合型的,但都是以以一维数组的方式为基的,只要理解数组的每一维属于哪种,用正常的方法解开(以上两种方式之一)一层一层解开就行了,不要看到N维数组就头痛。 呃说了一大堆,发现我只说数组,没有说对象如何使用,这是因为我大多用数组的关系,对象的循环与数组一样,只不过内部的使用格式不同罢了,可能 {$item.id}变成{$item->id}这样子,因为很少用对象模式输出数据库内容,又一直用smartyLight,所以smarty的 记不清了,但要使用的时候上百度,一分钟内就能找到答案。 附: 一般默认配置就可以使用了,但要更好的使用可能需要改一下配置。 PHP代码 $tpl->template_dir = __SITE_ROOT . “/templates/”; $tpl->compile_dir = __SITE_ROOT . “/templates_c/”; $tpl->config_dir = __SITE_ROOT . “/configs/”; $tpl->cache_dir = __SITE_ROOT . “/cache/”; $tpl->left_delimiter = ‘<{’; , $tpl->right_delimiter = ‘}>’; template_dir是模板目录,compile_dir是编译目录(不理解没关系,但必须有这个目录),最后两个是模板中使用变量的包含符,可以不用大括号以避开与js的冲突。这是因为js中有大括号 不过我还是喜欢用大括号做包含符,因为简单与习惯,也有办法避开js冲突。例如 XML/HTML代码 <script> {literal} function abc(){ //包含在{literal}中的代码不会被模板引擎解析,所以js中的大括号就与模板的大括号无关了。 } {/literal} </script>
要注意只有在js中有大括号的时候才需要用literal包含,如果只是外链的js就不需要了,因为没有大括号。js的冲突与解决方法同样适合于css代码。改模板包含符还是使用literal看你喜好了 总结: 其实用smarty还是很简单的,只不过把使用变量的方式改一下、再用DB类直接输出数组代替原来的过程式写法(如果不这么做,使用smarty会比较麻烦),重点就是记格式了,理解上没有难点。 附带说个非常有用的功能 XML/HTML代码 {include file=“header.tpl” title=foo} 在模板中可以用这个加载其它模板,而且你赋值的变量,在载入页 (header.tpl) 中仍然可以使用,不像phplib模板类那样还要再赋值。后面带的参数任意,title=foo表示在header.tpl页 中,$title变量值改为foo,这很有用,因为头文件中,通常标题,关键字,css文件路径要重新定义的。
|