深入探究Smarty模版

时间:2022-12-16 19:52:37

http://www.php10086.com/2012/02/387.html

简介:本文简要浅析smarty的工作机制,以及smarty其他配置和使用方法

smarty百科:

Smarty是一个使用PHP写出来的模板引擎,是目前业界最著名的PHP模板引擎之一。它分离了逻辑代码和外在的内容,提供了一种易于管理和使用的方法,用来将原本与HTML代码混杂在一起PHP代码逻辑分离

smarty优点:

1. 速度:采用Smarty编写的程序可以获得最大速度的提高,这一点是相对于其它的模板引擎技术而言的。

2. 编译型:采用Smarty编写的程序在运行时要编译成一个非模板技术的PHP文件,这个文件采用了PHP与HTML混合的方式,在下一次访问模板时将WEB请求直接转换到这个文件中,而不再进行模板重新编译(在源程序没有改动的情况下)

3. 缓存技术:Smarty选用的一种缓存技术,它可以将用户最终看到的HTML文件缓存成一个静态的HTML页,当设定Smarty的cache属性为true时,在Smarty设定的cachetime期内将用户的WEB请求直接转换到这个静态的HTML文件中来,这相当于调用一个静态的HTML文件。

4. 插件技术:Smarty可以自定义插件。插件实际就是一些自定义的函数。

5. 模板中可以使用if/elseif/else/endif。在模板文件使用判断语句可以非常方便的对模板进行格式重排。

 

PHP生成HTML静态页面

什么是html静态化?

说得简单点,就是把所有不是.htm或者.html的页面改为.htm或者.html

1.纯静态页面

当用户访问是,不需要经过服务器解析,直接就可以传送到客户端,此类型的页面,由于不需要解析就能直接访问,一般情况下,比动态页面的执行速度快。

2.静态化

页面静态化就是用动静结合的方式将动态网站生成静态网站来保存。这是实实在在的html文件,也就是静态页面。

3. 伪静态方法(Url静态化)

伪静态不是真正意义上的静态化,它只是利用某种方法将访问的路径也就是url地址转换成为.html为后缀的文件,但是实际上,文件本身还是以原来的后缀保存在服务器上。

 

本文主要指第二种方法静态化,动态生成html页面

HTML静态化的优点

一、减轻服务器负担。 
二、有利于搜索引擎优化seo,Baidu、Google都会优先收录静态页面,不仅被收录的快还收录的全; 
三、加快页面打开速度,静态页面无需连接数据库打开速度较动态页面有明显提高; 
四、HTML页面不会受程序相关漏洞的影响

模板的概念:

一组插入了HTML的脚本或者说是插入了脚本HTML,通过这种插入的内容来表示变化的数据。

传统PHP生成html页面

传统PHP生成html页面的原理

都是将模板读入内存然后调用parse()函数,用数据对预置的标记进行替换。

方法有两种:

1:就是用程序读取相应的数据来替换模版中的变量,然后生成静态页。php中主要用到的就是要用到fread()和fwirte()。而静态页面生成了之后,就会牵扯到修改的问题。这里可以用到正则匹配的方法来替换模版中改变的部位

$content = str_replace ("{file}",$file,$content);可以实现替换html的php变量{file}

PS:这种方法修改和更新效率不是很高,一般都用于那些变化不是很频繁的页面.

2:利用ob函数来

这里用到的函数主要是 ob_start(), ob_end_flush(), ob_get_content(),其中ob_start()是打开浏览器缓冲区的意思,打开缓冲后,所有来自PHP程序的非文件头信息均不会发送,而是保存在内部缓冲区,直到你使用了ob_end_flush().而这里最重要的一个函数,就是ob_get_contents(),这个函数的作用是获取缓冲区的内容

1 <?php
2    ob_start();
3    @readfile("http://localhost/?package=pricab&place_port=4");
4    $text = ob_get_flush();
5  
6    $myfile = fopen("myfile.html","w");
7  
8    $text  = str_replace ("{counent}",$string,$text);
9    fwrite($myfile,$text);
10    ob_clean();
11  ?>

 

smarty方式生成HTML静态页面

工作原理:

深入探究Smarty模版

Smarty的工作原理解析机制:

下面看看SMARTY是怎么做的。接到request后,先判断是否第一次请求该url,如果是,将该url所需的模板文件"编译"成php脚本,然后redirect;如果不是,就是说该url的模板已经被"编译"过了,检查不需要重编译后可以马上redirect,重编译条件可以自己设定为固定时限,默认的是模板文件被修改。

url判断方式:

$url=md5($_SERVER['REQUEST_URI']);//将当前页面的URL(包含?后面的所有参数)进行md5加密

$smarty->display(‘list2.html’,$url);//设置缓存文件名

需要注意的是:

$smarty->display(‘与之对应的模板文件名’,'缓存文件名的补充部分’)这个方法。

解析机制特点:

首先,除了第一次编译的成本比较高之外,只要不修改模板文件,编译好的cache脚本就随时可用,省去了大量的parse()时间;这种解析属于编译性解析,

其次SMARTY像PHP一样有丰富的函数库,从统计字数到自动缩进、文字环绕以及正则表达式都可以直接使用;如果觉得不够,比如需要数据结果集分页显示的功能,SMARTY还有很强的扩展能力,可以通过插件的形式进行扩充。

 

smarty编译性引申:

编译型语言写的程序执行之前,需要一个专门的编译过程,把程序编译成为机器语言的文件,比如exe文件,以后要运行的话就不用重新翻译了,直接使用编译的结果就行了(exe文件),因为翻译只做了一次,运行时不需要翻译,所以编译型语言的程序执行效率高。

解释性语言在运行程序的时候才翻译,比如解释性basic语言,专门有一个解释器能够直接执行basic程序,每个语句都是执行的时候才翻译。这样解释性语言每执行一次就要翻译一次,效率比较低。php也属于解释性语言

smarty缓存技术

要开启smarty的缓存,只需将caching设为true,并指定cache_dir即可.

使用cache_lefetime指定缓存生存时间,单位为秒

要对相同页面生成多个不同的缓存,在display或fetch中加入第二参数cache_id,如$smarty->display(\’index.tpl\’,$my_cache_id);此特性可用于对不同的$_GET进行不同的缓存

二、清除缓存

clear_all_cache();//清除所有缓存

clear_cache(\’index.tpl\’);//清除index.tpl的缓存

clear_cache(\’index.tpl\’,cache_id);//清除指定id的缓存

一般使用md5($tpl_file.$cache_id.$compile_id)作为唯一的cache_id

Smarty局部缓存的三种方法

在用smarty的时候,我们可能不希望缓存整个页面,比如说天气、股票等这些即时更新的信息。那么我们可以让其不缓存,有如下3种方法(目前我知道的!):

1,insert 法

Insert 函数类似欲 inluce 函数,不同之处是 insert 所包含的内容不会被缓存,每次调用该模板都会重新执行该函数。比如说我们定义一个显示时间的函数:

 
 
  1. function insert_get_current_time()
  2. {
  3. return date("H:i:s");

然后在模板中:

 
 
  1. {insert name="get_current_time"}

  这样每次打开页面,显示的都是即时时间,而不是缓存的。注意这里的函数名一定要以insert开头,模板中的name与之对应。如果我们的函数包含一些参数,那么我们的在模板中可以这样:

 
 
  1. {insert name="get_current_time" lid=#banner_location_id# sid=#site_id#}

那么Smarty 调用该函数类似insert_get_current_time(array("lid"=>"12345","sid"=>67890"));并将返回的结果显示在调用的位置。

2,动态block 法

在smarty代码中:

 
 
  1. function smarty_block_nocache($param,$content,$smarty)
  2.     {
  3.         return $content;
  4.     }
  5.     $smarty->register_block('nocache','smarty_block_nocache',false);

在模板文件中:

 
 
  1. <{nocache}>
  2.    //这里放不需要被缓存的内容
  3. <{/nocache}>

3,插件block 法

    这个跟block差不多,只是我们将其以插件的形式来做。在Smarty/plugins目录下建一个文件:block.nocache.php,这里命名一定要规范,否则smarty识别不了。 内容如下:

 
 
  1. function smarty_block_nocache($param,$content,$smarty)
  2.     {
  3.         return $content;
  4.     }

    在模板中和上面一直,不需要被缓存的地方加上nocache就可以了!

smarty优化方法

1. 在开发阶段结束后,网站上线后,关掉compile_check,即设置:compile_check = false;

2. 处理include标签,将多个小页面合并成完整的页面在进入编译.

3. 将css文件提前,可能的话将js文件放到页面下面,并压缩他们,(如果可以,你还可以合并他们)

4. 去掉页面注释,并压缩html代码.gzip(deflate甚至是:bzip2)输出页面,当然这也适合css,js文件的输出.注意是判断浏览器是否支持他们

 

参见:http://www.itlearner.com/article/4552

smarty其他知识点:

1、SMARTY缓存:$smarty->caching=true; 这样就开启了缓存,但是真正要起到减压的作用,还是需要is_cached()才能避免重复访问数据库。而is_cached()的参数,就是模板文件的名称了。如果is_cached()返回是false时,才读取数据库,并缓存。。这样,对访问量大而数据库访问又复杂的程序来说,作用可比提高服务器硬件配置的“性价比”来得高得多。

2、而同一页面的多版本,如:news.php?page=1这样情况下,就要为多个ID分配多个缓存版本,同样很简单,$smarty->display(‘index.tpl’,$page); 也就是在display后面多一个参数,$_GET["page"]的多版本缓存了。比如你的数据有十页,而SMARTY将会自在被用户访问以后,自动生成10个静态页面的缓存,当缓存期内其他用户再次访问时,只是读一个静态的HTML了,效率简直无与伦比。而这生成静态页面、是否过期等等一切操作,我们全部无需关心。。。

3、灵活运用SMARTY的cache_lifetime,有时,能启到相当强的效果。比如:大论坛,会员肯定相当多,这时,网站要即时显示“今天生日”的朋友,而这个功能,如果用到caching,理论上,可以做到接近于24小时才更新一次了。。。。。

4、SMARTY中可以使用GET、POST、SESSION等,但是,在开启了caching之后,请特别注意这些超级变量。。。因为caching会将这些数据都缓存起来,而下一个用户很可能在访问时,读到的是上一个用户的caching,这将是致命的。但还好,smarty为我们想得很周到,{nocache}{/nocache}标签对将解决这个问题,在此标签对内的内容将不会被缓存。。。。这时,可以将“动态”性强的东西放在这里就可以解决。

5、SMARTY有个小问题,就是默认的标签{}有可能与CSS和javascript中的{}冲突。当然,我们可以使用literal标签将之分开。还有一个问题,模板文件在dreamweaver中的表格内容,会当成文本来显示,这时,如果变量名称过长时(SMARTY中经常这样),将很不会那么“所见即所得”了,TABLE中td会失效。当然XHTML标签一样有这样的情况。以上两个问题,可以用一点来解决:把标签改为:<%{}%>这样,既不会与任何JS/CSS冲突,DW也会把这个认为是一个服务器端的脚本来“解析”,多长的变量名都不会“撑”破表格了。

6、SMARTY 的“人工”生成静态面,可能很少有人用过。不要写$smarty->display("index.tpl.html"),而改写成:$string=$smarty->fetch("index.tpl.html");这样,从模板读出的内容,经过一翻“替换”与处理后,内容不会直接显示出来,而是被赋值到了变量$string中。这时术可以使用fopen去“生成”一个静态的页面了,善用这个吧,在一些特殊情况下,比smarty本身的缓存还有效率。