配色: 字号:
PHP-关于模板的原理和解析
2016-08-20 | 阅:  转:  |  分享 
  
PHP-关于模板的原理和解析

将PHP代码和静态HTML代码进行分离,使代码的可读性和维护性得到显著提高。

使用模板引擎:

??我们所说的模板是Web模板,是主要由HTML标记组成的语言来编写的页面,但也有如何表示包含动态生成内容的方式(解析标签)。模板引擎是一种软件库,允许我们从模板生成HTML代码,并指定要包含的动态内容。

模板引擎的特点:

1.鼓励分离:让更个系统的可读性和维护性得到提高。2.促进分工:使得程序员和美工去专心处理自己的设计。3.比PHP更容易解析:编译文件和缓存文件加载更快、占资源更少。4.增加安全性:可限制模板设计师进行不安全的操作的能力避免误删误访问等。

模板处理的流程图



?

创建模板:

1、创建初始模板所需要的文件夹和文件。

a)index.php主文件,用于编写业务逻辑。b)template.inc.php模板初始化文件,用于初始模版信息。c)templates目录存放所有的模板文件。d)templates_c目录存放所有编译文件。e)cache目录存放所有缓存文件。f)includes目录存放所有的类文件。g)config目录存放模板系统变量配置文件。



以下是源码:

主文件index.php



php

//index.php

//设置编码为UTF-8header(''Content-Type:text/html;Charset=utf-8'');//网站根目录define(''ROOT_PATH'',dirname(__FILE__));//存放模板文件夹define(''TPL_DIR'',ROOT_PATH.''/templates/'');//编译文件夹define(''TPL_C_DIR'',ROOT_PATH.''/templates_c/'');//缓存文件夹define(''CACHE_DIR'',ROOT_PATH.''/cache/'');//定义缓存状态define(''IS_CACHE'',true);//设置缓存状态开关IS_CACHE?ob_start():null;includeROOT_PATH.''/includes/Templates.class.php'';

$_name=''方块李'';



$array=array(1,2,3,4,5,6);

$_tpl=newTemplates();

$_tpl->assign(''name'',$_name);

$_tpl->assign(''a'',5>4);

$_tpl->assign(''array'',$array);

//显示

$_tpl->display(''index.tpl'');

?>



模板文件HTML

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27 DOCTYPE?htmlPUBLIC"-//W3C//DTDXHTML1.0Transitional//EN""/TR/xhtml1/DTD/xhtml1-transitional.dtd">







title><br><br>?<br><br>head><br><br><body><br><br>{include"test.php"}<br><br>{#}这是一条PHP的注释,在HTML页面里是不显示的,只会在生成的编译文件里显示{#}<br><br>我将被index.php导入<br><br>{$name}这个标签必须经过Parser.class.php这个解析类来解析它1<br><br><br?/><br><br>这里的内容改变了,为什么?<br><br><br?/><br><br>{if$a}<br><br>显示一号皮肤<br><br>{else}<br><br>显示二号皮肤<br><br>{/if}<br><br><br?/><br><br>{foreach$array(kewww.shanxiwang.nety,value)}<br><br>{@key}....{@value}<br?/><br><br>{/foreach}<br><br>body><br><br>html> <br><br>模板类:<br><br>+ViewCode<br><br>解析类:<br><br>1<br><br>2<br><br>3<br><br>4<br><br>5<br><br>6<br><br>7<br><br>8<br><br>9<br><br>10<br><br>11<br><br>12<br><br>13<br><br>14<br><br>15<br><br>16<br><br>17<br><br>18<br><br>19<br><br>20<br><br>21<br><br>22<br><br>23<br><br>24<br><br>25<br><br>26<br><br>27<br><br>28<br><br>29<br><br>30<br><br>31<br><br>32<br><br>33<br><br>34<br><br>35<br><br>36<br><br>37<br><br>38<br><br>39<br><br>40<br><br>41<br><br>42<br><br>43<br><br>44<br><br>45<br><br>46<br><br>47<br><br>48<br><br>49<br><br>50<br><br>51<br><br>52<br><br>53<br><br>54<br><br>55<br><br>56<br><br>57<br><br>58<br><br>59<br><br>60<br><br>61<br><br>62<br><br>63<br><br>64<br><br>65<br><br>66<br><br>67<br><br>68<br><br>69<br><br>70<br><br>71<br><br>72<br><br>73<br><br>74<br><br>75<br><br>76<br><br>77<br><br>78<br><br>79<br><br>80<br><br>81<br><br>82<br><br>83<br><br>84<br><br>85<br><br>86<br><br>87<br><br>88<br><br>89<br><br>90<br><br>91<br><br>92<br><br>93<br><br>94<br><br>95<br><br>96<br><br>97<br><br>98<br><br>99<br><br>100<br><br>101<br><br>102<br><br>103<br><br>104<br><br>105<br><br>106<br><br>107<br><br>108<br><br>109<br><br>110<br><br>111<br><br>112<br><br>113<br><br>114<br><br>115<br><br>116<br><br>117 //Parser.class.php<br><br>????class?Parser{<br><br>????????//获取模板内容<br><br>????????private?$_tpl;<br><br>????????//构造方法,初始化模板<br><br>????????public?function?__construct($_tplFile){<br><br>????????????//判断文件是否存在<br><br>????????????if(!$this->_tpl=?file_get_contents($_tplFile)){<br><br>????????????????exit(''ERROR:读取模板出错!'');<br><br>????????????}<br><br>????????????<br><br>????????}<br><br>????????<br><br>????????//解析普通变量<br><br>????????private?function?parVar(){<br><br>????????????$_pattern?=?''/\{\$([\w]+)\}/'';<br><br>????????????if?(preg_match($_pattern,$this->_tpl)){<br><br>????????????????$this->_tpl=preg_replace($_pattern,"_vars[''$1'']?>",$this->_tpl);<br><br>????????????}<br><br>????????}<br><br>????????//解析IF条件语句<br><br>????????private?function?parIf(){<br><br>????????????//开头if模式<br><br>????????????$_patternIf?=?''/\{if\s+\$([\w]+)\}/'';<br><br>????????????//结尾if模式<br><br>????????????$_patternEnd?=?''/\{\/if\}/'';<br><br>????????????//else模式<br><br>????????????$_patternElse?=?''/\{else\}/'';<br><br>????????????//判断if是否存在<br><br>????????????if(preg_match($_patternIf,?$this->_tpl)){<br><br>????????????????//判断是否有if结尾<br><br>????????????????if(preg_match($_patternEnd,?$this->_tpl)){<br><br>????????????????????//替换开头IF<br><br>????????????????????$this->_tpl=preg_replace($_patternIf,?"_vars[''$1'']){?>",?$this->_tpl);<br><br>????????????????????//替换结尾IF<br><br>????????????????????$this->_tpl=preg_replace($_patternEnd,?"",?$this->_tpl);<br><br>????????????????????//判断是否有else<br><br>????????????????????if(preg_match($_patternElse,?$this->_tpl)){<br><br>????????????????????????//替换else<br><br>????????????????????????$this->_tpl=preg_replace($_patternElse,?"",?$this->_tpl);<br><br>????????????????????}<br><br>????????????????}else{<br><br>????????????????????exit(''ERROR:语句没有关闭!'');<br><br>????????????????}<br><br>????????????}<br><br>????????}<br><br>????????//解析foreach<br><br>????????private?function?parForeach(){<br><br>????????????$_patternForeach?=?''/\{foreach\s+\$(\w+)\((\w+),(\w+)\)\}/'';<br><br>????????????$_patternEndForeach?=?''/\{\/foreach\}/'';<br><br>????????????//foreach里的值<br><br>????????????$_patternVar?=?''/\{@(\w+)\}/'';<br><br>????????????//判断是否存在<br><br>????????????if(preg_match($_patternForeach,?$this->_tpl)){<br><br>????????????????//判断结束标志<br><br>????????????????if(preg_match($_patternEndForeach,?$this->_tpl)){<br><br>????????????????????//替换开头<br><br>????????????????????$this->_tpl=preg_replace($_patternForeach,?"_vars[''$1'']as\$$2=>\$$3){?>",?$this->_tpl);<br><br>????????????????????//替换结束<br><br>????????????????????$this->_tpl=preg_replace($_patternEndForeach,?"",?$this->_tpl);<br><br>????????????????????//替换值<br><br>????????????????????$this->_tpl=preg_replace($_patternVar,?"",?$this->_tpl);<br><br>????????????????}else{<br><br>????????????????????exit(''ERROR:Foreach语句没有关闭'');<br><br>????????????????}<br><br>????????????}<br><br>????????}<br><br>????????//解析include<br><br>????????private?function?parInclude(){<br><br>????????????$_pattern?=?''/\{include\s+\"(.)\"\}/'';<br><br>????????????if(preg_match($_pattern,?$this->_tpl,$_file)){<br><br>????????????????//判断头文件是否存在<br><br>????????????????if(!file_exists($_file[1])||?empty($_file[1])){<br><br>????????????????????exit(''ERROR:包含文件不存在!'');<br><br>????????????????}<br><br>????????????????//替换内容<br><br>????????????????$this->_tpl=preg_replace($_pattern,?"",?$this->_tpl);<br><br>????????????}<br><br>????????}<br><br>????????//解析系统变量<br><br>????????private?function?configVar(){<br><br>????????????$_pattern?=?''//'';<br><br>????????????if(preg_match($_pattern,?$this->_tpl,$_file)){<br><br>????????????????$this->_tpl=preg_replace($_pattern,"_config[''$1'']?>",?$this->_tpl);<br><br>????????????????<br><br>????????????}<br><br>????????}<br><br>????????<br><br>????????//解析单行PHP注释<br><br>????????private?function?parCommon(){<br><br>????????????$_pattern?=?''/\{#\}(.)\{#\}/'';<br><br>????????????if(preg_match($_pattern,?$this->_tpl)){<br><br>????????????????$this->_tpl=preg_replace($_pattern,?"",?$this->_tpl);<br><br>????????????}<br><br>????????}<br><br>????????<br><br>????????<br><br>????????//生成编译文件<br><br>????????public?function?compile($_parFile){<br><br>????????????//解析模板变量<br><br>????????????$this->parVar();<br><br>????????????//解析IF<br><br>????????????$this->parIf();<br><br>????????????//解析注释<br><br>????????????$this->parCommon();<br><br>????????????//解析Foreach<br><br>????????????$this->parForeach();<br><br>????????????//解析include<br><br>????????????$this->parInclude();<br><br>????????????//解析系统变量<br><br>????????????$this->configVar();<br><br>????????????//生成编译文件<br><br>????????????if(!file_put_contents($_parFile,?$this->_tpl)){<br><br>????????????????exit(''ERROR:编译文件生成失败!'');<br><br>????????????}<br><br>????????}<br><br>????} <br><br>总结:模板引擎的整个过程:<br><br>1、当浏览器请求index.php文件时,实例化模板类对像?$_tpl=newTemplates();<br><br>2、当Templates实例化的时候,生成两个数组,一个用来存放模板变量,另一个存放系统变量,通过构造方法,判断文件夹是否存在,同时通过XML文件将系统变量数组初始化<br><br>3、通过模板类Templates的注入方法,assign(),将对应模板index.tpl中变量的index.php的内容注入到模板类的私有变量,完成初始化<br><br>4、模板类Templates类显示方法display()通过实例化解析类Parser,将取到的注入变量通过解析类进行解析(即替换)<br><br>5、解析(替换)后,将文件写入PHP、HTML混全文件<br><br>6、通过Templates类的显示方法将文件输出:<br><br>1、第一次执行显示方法时,将会把PHP、HTML混合文件,生成纯静态的缓存文件<br><br>2、调用缓存文件,显示页面<br><br>3、当浏览器再次调用显示方法时,首先根据各文件的最后修改时间,判断是否重新生成缓存文件或直接调用已存在的缓存文件<br><br>重点:<br><br>1、通过正则表达式进行字符串的替换<br><br>2、熟悉OOP<br><br><br><br></td> </tr> </tbody> </table> <div id="viewerPlaceHolder" style="width: 717px; height: 700px; display: none;"> </div> </span> <table> <tbody> <tr> <td></td> </tr> </tbody> </table> </td> </tr> <tr> <td> <div class="left list" style="text-align: left; font-size: 14px;"> <div id='lastart'></div> <div id='nextart'></div> </div> </td> </tr> <tr> <td style="height: 29px;"> <div style="padding-top: 20px;"> <table style="width: 100%;" cellpadding="0" cellspacing="0"> <tbody> <tr> <td width="31%"></td> <td> <table cellpadding="0" cellspacing="0" style="margin: 0px auto;"> <tbody> <tr> <td><div class=" left" style='cursor: pointer'> <a href="javascript:void(0);" onclick="wzhit(22);SaveArt();"> <img src="http://pubimage.360doc.com/wz/tb11.gif" /></a> </div> <div class=" left xianhua" id="sendFlowerToUser" style='cursor: pointer' onclick='Showflowerlayer("sendedLayer1");'> 献花(<span id="articleflowernum">0</span>)<div id='flowernumadd' class="addtionone">+1</div> </div> </td> </tr> </tbody> </table> </td> <td width="31%" style="vertical-align: bottom; font-size: 12px;"> <div class="right" id="sharediv2"> </div> </td> </tr> </tbody> </table> </div> </td> </tr> <tr> <td> <div class="xiantao" style="padding-top: 5px;"> </div> </td> </tr> <tr> <td class="xgiambox" style="vertical-align: top; height: 30px; padding-top: 10px;"> <div class="right">(本文系<span class="name"><a target="_blank" href="http://www.360doc.com/userhome/16853537">网络学习天...</a></span>首藏<span id="docsource"></span>)</div> </td> </tr> </tbody> </table> </td> </tr> </tbody> </table> </td> </tr> </tbody> </table> <div class="lswzbox"> <div> <table cellpadding="0" cellspacing="0"> <tbody> <tr> <td> <div class="bottom_article f_left"> <div class="str_border"> <strong>类似文章</strong> <a href='http://www.360doc.com/relevant/584492879_more.shtml' target='_blank' class='a_more f_right' onclick='artStatistics("20-9-8");'>更多</a> </div> <ul class="barticle_list"> <li><span><a href=http://www.360doc.com/content/21/1022/09/34111202_1000809524.shtml target=_blank onclick='artStatistics("20-9-7");'>编程语言php制作简单模版引擎,php模版引擎_PHP教程</a></span></li> <li><span><a href=http://www.360doc.com/content/06/0811/21/8554_179080.shtml target=_blank onclick='artStatistics("20-9-7");'>smarty实例教程 </a></span></li> <li><span><a href=http://www.360doc.com/content/12/0518/07/1372409_211801982.shtml target=_blank onclick='artStatistics("20-9-7");'>smarty 原来也不过如此~~呵呵</a></span></li> <li><span><a href=http://www.360doc.com/content/18/0915/07/11935121_786792761.shtml target=_blank onclick='artStatistics("20-9-7");'>PHP学习Thinkphp框架(2)——数据库查询,添加操作和Think模板引擎</a></span></li> <li><span><a href=http://www.360doc.com/content/19/1027/08/6519614_869296865.shtml target=_blank onclick='artStatistics("20-9-7");'>PHP之Smarty模板引擎</a></span></li> <li><span><a href=http://www.360doc.com/content/12/0423/15/9256994_205911895.shtml target=_blank onclick='artStatistics("20-9-7");'>SMARTY环境下合理的网站结构</a></span></li> <li><span><a href=http://www.360doc.com/content/12/1016/20/7851074_241889086.shtml target=_blank onclick='artStatistics("20-9-7");'>最简单的PHP模板技术</a></span></li> <li><span><a href=http://www.360doc.com/content/08/1017/11/75523_1778394.shtml target=_blank onclick='artStatistics("20-9-7");'>从头学习Drupal--基本架构四 | Drupal China</a></span></li> <li><span><a href=http://www.360doc.com/content/12/1220/15/7312479_255295691.shtml target=_blank onclick='artStatistics("20-9-7");'>html.tpl.php模板文件可用的标准变量</a></span></li> </ul> </div> </td> </tr> </tbody> </table> <div id="Reflction"> <div id="360docRefTN"> </div> <div id="360docRefCT"> </div> <div id="360docRefPB" align="center"> </div> </div> <a name="sf"></a> <div id="ReflectionPart"> <div class="mainbottom"> <div class=" left"> <img src="http://pubimage.360doc.com/wz/tb22.gif" /> </div> <div class="plbox left"> <div class="plmain"> <div class="titwx">发表评论:</div> <div> <textarea name="SendRefTB" class="pltxt" id="SendRefTB" onfocus="testContent(1);" onblur="testContent(2)"></textarea> </div> <div class="right"> <img id="ImgSendPL" src="http://pubimage.360doc.com/wz/tb24.gif" style="cursor: pointer;" onclick="SubmitReflection()" width="75" height="28" /> </div> </div> </div> <div class=" left"> <img src="http://pubimage.360doc.com/wz/tb23.gif" /> </div> </div> </div> </div> </div> </td> <td align="center" valign="top" width="18px"></td> <td align="left" valign="top" width="252px"></td> </tr> </tbody> </table> </div> <script language="javascript" type="text/javascript"> var appName = navigator.appName.toLowerCase(); if (appName.indexOf("microsoft internet explorer") > -1) { document.write("<scr" + "ipt type='text/javascript' src='http://www.360doc.com/js/StickySystemIENewVersion.js?t=2012122401'></sc" + "ript>"); } else { document.write("<scr" + "ipt type='text/javascript' src='http://www.360doc.com/js/StickySystemOtherNewVersion.js?t=2012122401'></sc" + "ript>"); } </script> <span id="LayerLogin"></span> <script>GerLookingUserInfo(1,16853537,1,52,'http://flash10.360doc.com/2016/0820/09/584492879_1.swf',8,10);OutputSource('http://www.360doc.com/userhome/16853537');OutputCategory(16853537,1,'馆藏分类');</script> <script src="http://blockart.360doc.com/ajax/getstatusv2.ashx?aid=584492879" type="text/javascript" charset="utf-8" async="async"></script> <script type="application/ld+json"> { "@context": "https://ziyuan.baidu.com/contexts/cambrian.jsonld", "@id": "http://www.360doc.com/document/16/0820/09/16853537_584492879.shtml", "title": "PHP-关于模板的原理和解析", "pubDate": "2016-08-20T09:09:32" } </script> </body> </html>