PHP基础(025)---Smarty模板

Smarty模板  ---PHP 最早的MVC模板引擎

Smarty 软件包下载地址 : http://www.smarty.net/download

Smarty是基于MVC(Model - View - Controller )框架概念,由模型-视图-控制器构成:

  1. 视图 : 就是提供给用户的界面;
  2. 控制器 : 负责处理视图和模型的对应关系,并将视图收集的信息传递给对应的模型。
  3. 模型 : 对接收过来的信息进行处理,并将处理结果回传给视图。

Smarty 特点:

  1. 可以自行设置模板定界符,所以可以使用{} , {{}} , <?-- {} --> 等;
  2. 仅对修改过的模板文件进行重新编译;
  3. 模板中可以使用if/elseif/else/endif ;
  4. 内建缓存支持;
  5. 可自定义插件 ;
  6. 待补...

Smarty安装:

我这里下载的是“Smarty-3.1.18.zip”,先解压,再将解压得到的libs目录存到E:\XMAPP\htdocs\根目录(也可以存到其他地方或子文件夹中,只引入到smarty类库即可),并重新命名为"Smarty3" ;

测试第一个smarty程序"hello world " :

第一步:在Smarty3下面新建四个文件夹,如下:

第二步:将这四个文件夹更名分:templates, templates_c, configscache。(强烈建议分别在每个使用Smarty的程序中都单独定义这些目录。)

第三步:在E:\XMAPP\htdocs\Smarty3\templates目录下面,新建一个index.tpl文件(或html文件):

 1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 2 <html xmlns="http://www.w3.org/1999/xhtml">
 3 <head>
 4 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
 5 <title>{ $title }</title>
 6 </head>
 7 <body>
 8 {$content}
 9 </body>
10 </html>
View Code

第四步 :在E:\XMAPP\htdocs\根目录下新建一个"helloworld.php" ;然后在EditPlus点击浏览器阅览:

 1 <?php
 2 /*  定义服务器的绝对路径  */
 3 define('BASE_PATH','E:\XMAPP\htdocs\\'); //对着这个文件入径配置即可 :E:\XMAPP\htdocs\Smarty3\templates
 4 /*  定义Smarty目录的绝地你路径  */
 5 define('SMARTY_PATH','Smarty3\\');
 6 /*  加载Smarty类库文件    */
 7 require BASE_PATH.SMARTY_PATH.'Smarty.class.php';
 8 /*  实例化一个Smarty对象  */
 9 $smarty = new Smarty;
10 /*  定义各个目录的路径    */
11 $smarty->template_dir = BASE_PATH.SMARTY_PATH.'templates/';
12 $smarty->compile_dir = BASE_PATH.SMARTY_PATH.'templates_c/';
13 $smarty->config_dir = BASE_PATH.SMARTY_PATH.'configs/';
14 $smarty->cache_dir = BASE_PATH.SMARTY_PATH.'cache/';
15 /*  使用Smarty赋值方法将一对儿名称/方法发送到模板中  */
16 $smarty->assign('title','第一个Smarty程序');
17 $smarty->assign('content','Hello world ,你好! \'Smarty\'!');
18 /*  显示模板  */
19 $smarty->display('index.tpl'); //或者用html为后缀也行
20 ?>
View Code

输出: “Hello world,你好!'Smarty'!

Smarty配置:

因为在实际开发中,一个项目所使用到的页面可能有上百个,不能每个页面都要重写一遍Smarty.class.php文件的连接,也不能为每个页面都建4个标准的文件夹去运作程序。为了避免这种情况,那么就是要对smarty模板的位置和相关配置进行规划。定义配置文件config.php,并存到E:\XMAPP\htdocs\根目录下.

其代码如下:

 1 <?php
 2 /*  定义服务器的绝对路径  */
 3 define('BASE_PATH','E:\XMAPP\htdocs\\'); ////对着这个文件入径配置即可 E:\XMAPP\htdocs\Smarty3\
 4 /*  定义Smarty目录的绝地你路径  */
 5 define('SMARTY_PATH','Smarty3\\');
 6 /*  加载Smarty类库文件    */
 7 require BASE_PATH.SMARTY_PATH.'Smarty.class.php';
 8 /*  实例化一个Smarty对象  */
 9 $smarty = new Smarty;
10 /*  定义各个目录的路径    */
11 $smarty->template_dir = BASE_PATH.SMARTY_PATH.'templates/';
12 $smarty->compile_dir = BASE_PATH.SMARTY_PATH.'templates_c/';
13 $smarty->config_dir = BASE_PATH.SMARTY_PATH.'configs/';
14 $smarty->cache_dir = BASE_PATH.SMARTY_PATH.'cache/';
15 /*  调试控制台  */
16 //$smarty->debugging = true;
17 /*  定义定界符  */
18 //$smarty->left_delimiter = '<{';
19 //$smarty->right_delimiter = '}>';
20 ?>
View Code

那么因此上面的"helloworld.php"代码就变为了:

 1 <?php
 2 /*  引入配置文件  */
 3 include_once"config.php";
 4 
 5 /*  使用Smarty赋值方法将一对儿名称/方法发送到模板中  */
 6 $smarty->assign('title','第一个Smarty程序');
 7 $smarty->assign('content','Hello world,你好!\'Smarty\'!');
 8 /*  显示模板  */
 9 $smarty->display('index.html'); //或者用html为后缀也行
10 ?>
View Code

Smarty模板的设计:

 Smarty的特点是将用户界面和过程实现分离,让美工和程序员各司其职,互不干扰。

-》smarty模板文件是由一个页面中所有的静态元素,加上一些定界符"{...}"组成的。模板文件统一存放的位置是templates目录下。模板中的不允许出现PHP代码段。smarty模板中的所有注释,变量,函数等都要包含在定界符内。

-》注释:smarty中的注释和PHP注释类似,都不会显示在源代码当中。注释包含在两个星号"*"中间,格式如下: {* remark *}

-》变量 :

  1. 来自PHP页面中的变量,也就是assign()方法传过来的变量。
  2. 保留变量,相当于PHP中的预定义变量。(Smarty模板中使用的保留变量有:get,post,server,session,cookie,request,now,const,config )
  3. 从配置文件中读取数据,Smarty模板也可以通过配置文件来赋值。
    • 第一种使用"#"号,将变量名置于两个"#"号中间,即可像普通变量一样调用配置文件内容。
    • 第二种使用变量中的$smarty_config.来调用配置文件。
    • 补充在tpl文件中加载conf文件的方法是在tpl文件的第一行输入" { config_load file="myconf.conf" } " ;

-》修饰变量(Variable modifers ) : 格式[变量名|修饰变量的方法名:参数1:参数2:参数3...],在对变量进行修饰时,不仅可以单独使用,也可以多个使用,每个方法之间同样用“|"来分隔,例如{$str|nl2br|upper}

修饰变量的常用方法名有caplitalize(首字母大写),count_characters:true/false(变量中的字符串个数。如果后面有参数true,则空格也被计算。否则忽略空格),upper(将变量改为大写),strip_tags(去掉所有html标签),等。

-》流程控制:

  1. {if}...{else}...{/if} + 常用运算符(<,>,/,=,!=,eq,ne,lt,lte,is even,is odd, not,mod,div by等修饰词修饰)
  2. {foreach name=foreach_name key=key item=item from=arr_name}...{/foreach} ---其中item和from是必要参数,不可省略
  3. {section name="sec_name" loop=$arr_name start=num step=nem}...{/section}

Smarty程序设计:

-》smarty中的常用方法:在PHP文件中除了assign,display方法,还有其它方法比较常用:

  1. void append() ---该方法向数组中追加元素
  2. void clear_all_assign() ---清除所有模板中的赋值
  3. void clear_assign() ---清除一个指定的赋值
  4. void config_load() ---加载配置文件
  5. string fetch() ---返回模板的输出内容,但不直接显示出来
  6. array get_config_vars() ---获取指定配置变量的值,如果没有参数,则返回一个所有配置变量的数组
  7. array get_template_vars() ---获取指定模板变量的值 ,如果没有参数,则返回一个所有模板变量的数组
  8. bool template_exists() ---检测指定的模板是否存在

-》smarty的配置变量:

  1. 常量: SMARTY_DIR ---用来保存Smarty类库的完整路径
  2. 变量: $template_dir  ---模板目录
  3. 变量: $compile_dir ---编译目录
  4. 变量: $cache_dir ---缓存目录
  5. 变量:$config_dir ---配置目录
  6. 变量:$debugging---调试变量
  7. 变量: $caching---缓存变量

Smarty缓存:

1.在smarty中控制缓存

<?php
    require('libs/Smarty.class.php');
    $smarty= new Smarty;
    //建立缓存
    $smarty->caching=true;           // 启用缓存
    $smarty->cache_dir="./cache/"; //指定缓存目录
    //缓存的生命周期
    $smarty->cache_lifetime=60*60*24; //设置缓存时间为1天    
     
       
    $smarty->display('index.tpl');  //单个页面输出保存
    //每个页面多个缓存
    $smarty->display('index.tpl',$_GET["newsid"]);   //通过id传递
?>   
 

 2.判断是否被缓存了:(下例中is_cache()和display()两个方法,使用的参数是相同的。)

if(!$smarty->is_cache('news.tpl',$_GET["newsid"])){

  $smarty->assign(...);

}

$smarty->displary('news.tpl',$_GET["newsid"]);

3.清除缓存:

<?php
    require('libs/Smarty.class.php');
    $smarty= new Smarty();
    $smarty->caching=true;
    $smarty->clear_all_cache();                             //清除所有的缓存文件
    $smarty->clear_cache('index.tpl');                   //清除某一模板的缓存
    $smarty->clear_cache('index.tpl',"CACHEID");  //清除某一模板的多个缓存中指定缓存号的一个
    $smarty->display('index.tpl');
?>

 4.关闭局部缓存:

首先定义一个插件函数block.cacheless.php,并将其存放在smarty的plugins目录下,文件代码如下:

<?php
    function smarty_block_cacheless($param,$content,&$smarty){
        return $content;
}
?>

 然后将Smarty的源文件Smarty_Compiler.class.php打开,找到下面的一句:

$this->_plugins['block'][$tag_command]=array($plugin_func,null,null,null,true); //将其最后一个参数改成flase

最后在test.tpl中编写相应的代码:

<{cacheless}> 此标签内是不需要缓存的内容<{/cacheless}>

备注:在相关的显示部分,例如实时比分,广告,时间等,使用<{cacheless}>。。。 <{/cacheless}>自定义的smarty块标记,关闭不需要缓存的内容。

 

 

其他内容补充代码:

<test.php>

<?php
	include "./libs/Smarty.class.php";             	//包含Smarty类库所在的文件
	require("Page_class.php");                  	//包含分页类Page所在的文件
	require("MyDB_class.php");                	//包含数据库读取类所在的文件

	$tpl = new Smarty();                      	//创建一个Smarty类的对象$tpl
	$tpl->template_dir = "./templates/";          	//设置所有模板文件存放的目录
	$tpl->compile_dir = "./templates_c/";         	//设置所有编译过的模板文件存放的目录
	$tpl->cache_dir = "./cache/";                	//设置存放Smarty缓存文件的目录
	$tpl->caching=1;                         	//设置开关Smarty缓存模板功能属性,这里为开启
	$tpl->cache_lifetime=60*60;                	//设置模板缓存有效时间段的长度,这里为1小时
	$tpl->left_delimiter = '<{';                  	//设置模板语言中的左结束符
	$tpl->right_delimiter = '}>';

	  //下面的代码需要一个个的测试单元打开

	$tpl->assign('title',"Smarty实现商品列表"); //将title中的字母转成大写
/*补充变量多个修改器
*{$articleTitle}
*{$articleTitle|upper|spacify}
*{$articleTitle|lower|spacify|truncate}
*{$articleTitle|lower|truncate:30|spacify}
*{$articleTitle|lower|spacify|truncate:30:". . ."}
*/

/*
* 1){include file="header.tpl"} {* body of template goes here *}	 {include file="footer.tpl"}
*  2)还可以{* 绝对路径或 $trusted_dir 的相对路径 *} {include_php file="/path/to/load_nav.php"}
*  3)smarty insert : 使模板的一部分不被缓存. 如果打开了缓存, insert 函数却不会被缓存,每次调用页面它们都会被动态加载,即使是在缓存页面中. 该特性可以广泛应用于广告条、投票、实时天气预报、搜索结果、反馈信息等区域.
*  4)smarty Literal 标签区域内的数据将被当作文本处理,此时模板将忽略其内部的所有字符信息. 该特性用于显示有可能包含大括号等字符信息的 javascript 脚本. 当这些信息处于 {literal}{/literal} 标签中时,模板引擎将不分析它们,而直接显示.
*
*/

	 //开始测试一:Smarty strip去除多余空格实例代码教程 - 用一个空格或一个给定字符替换所有重复空格,换行和制表符.
	$tpl->assign('articleTitle', "Grandmother of\neight makes\t hole in one.");

	  //开始测试二:数组
//	 $contact=array(                               //将一个人的联系信息保存在一个关联数组中
//		'fax' => '555-222-9876',
//		'email' => 'gao@lampbrother.net',
//		'phone' => array(
//			'home' => '555-444-3333',
//			'cell' => '555-111-1234'
//			)
//		);
//	$tpl->assign('contact', $contact);          //将关联数组$contact分配到模板中使用
//
//	$contact2=array(                               //将一个人的联系信息保存在一个索引数组中
//		'555-222-9876',
//		'gao@lampbrother.net',
//	 	 array( '555-444-3333', '555-111-1234')
//	 	);
//	$tpl->assign('contact2', $contact2);       //将索引数组$contact2分配到模板中使用
//
//	$contact3=array(                               //使用索引和关联数组保存联系信息
//		'fax' => '555-222-9876',
//	 	array('first'=>'gao@lampbrother.net','second'=>'feng@lampbrother.net'),
//		'phone' => array('555-444-3333','555-111-1234')
//		);
//	$tpl->assign('contact3', $contact3);        //将混合数组$contact3分配到模板中使用



	 //开始测试三:循环	foreach; 测试四section
	 /*
	 * 模板的 section 用于遍历数组中的数据. section 标签必须成对出现. 必须设置 name 和 loop 属性. 名称可以是包含字母、数字和下划线的任意组合. 可以嵌套但必须保证嵌套的 name 唯一. 变量 loop (通常是数组)决定循环执行的次数. 当需要在 section 循环内输出变量时,必须在变量后加上中括号包含着的 name 变量. sectionelse 当 loop 变量无值时被执行.
	 *
	 *
	 *
	 */
	 $contact4=array(                           	//声明一个保存三个联系人信息的二维数组
		array('name'=>'高某','fax'=>'1234','email'=>'gao@lampbrother.net','phone'=>'4321'),
		array('name'=>'洛某','fax'=>'4567','email'=>'luo@lampbrother.net','phone'=>'7654'),
		array('name'=>'峰某','fax'=>'8910','email'=>'feng@lampbrother.net','phone'=>'0198')
	);
	$tpl->assign('contact4', $contact4);          //将关联数组$contact分配到模板中使用
	//测试三完

//测试五开始
$id = array(1001,1002,1003);
$tpl->assign('custid',$id);

$fullnames = array('John Smith','Jack Jones','Jane Munson');
$tpl->assign('name',$fullnames);

$addr = array('253 N 45th', '417 Mulberry ln', '5605 apple st');
$tpl->assign('address',$addr);

$types = array(
           array( 'home phone', 'cell phone', 'e-mail'),
           array( 'home phone', 'web'),
           array( 'cell phone')
         );
$tpl->assign('contact_type', $types);

$info = array(
           array('555-555-5555', '666-555-5555', 'john@myexample.com'),
           array( '123-456-4', 'www.example.com'),
           array( '0457878')
        );
$tpl->assign('contact_info', $info);
 //测试五结束


$tpl->display("test.tpl");
?>

 <test.tpl>

<html>
	<head><title><{$title|upper}></title></head>
	<body>

	 <!-- this is a comment 这里是模板注释 -->
     <{$articleTitle}>
		<{$articleTitle|strip}>
		<{$articleTitle|strip:" "}>
		<!--
		Grandmother of
eight makes	 hole in one.
		Grandmother of eight makes hole in one.
		Grandmother of eight makes hole in one.	
		-->

		<p>访问从PHP中分配的关联数组:
	电子邮件:<{$contact.email}>  家庭电话:<{$contact.phone.home}><br>
访问从PHP中分配的索引数组:
	电子邮件:<{$contact2[1]}>  家庭电话:<{$contact2[2][0]}><br>
访问从PHP中分配的索引和关联混合数组:
	第一个电子邮件:<{$contact3[0].first}>  家庭电话:<{$contact3.phone[0]}><br></p>

	<!--测试三开始-->
	<div>
	<!--<table border="1" width="80%" align="center">
			<caption><h1>联系人信息</h1></caption>
			<tr>
				<th>姓名</th><th>传真</th><th>电子邮件</th><th>联系电话</th>
			</tr>
			<{foreach from=$contact4 item=row}>        <{* 外层foreach遍历数组$contact4 *}>
				<tr>                            <{* 输出表格的行开始标记 *}>
				<{foreach from=$row item=col}>       <{* 内层foreach遍历数组$row *}>
					<td><{$col}></td>	             <{* 以表格形式输出数组中的每个数据 *}>
				<{/foreach}>                       <{* 内层foreach区块结束标记 *}>
				</tr>                           <{* 输出表格的行结束标记 *}>
			<{/foreach}>                           <{* 外层foreach区域的结束标记 *}>
		</table>

		<!--测试三结束--> -->
		</div>

		<div>
		<!--测试四开始-->
	<table border="1" width="80%" align="center">
	<caption><h1>联系人信息</h1></caption>
	<tr>
		<th>姓名</th><th>传真</th><th>电子邮件</th><th>联系电话</th>
	</tr>
	<{section name=line loop=$contact4}>          <{* 使用section遍历数组$contact *}>
		<tr>                              <{* 输出表格的行开始标记 *}>
			<td><{$contact4[line].name}></td>   <{* 输出数组第二维中下标为name的元素值 *}>
			<td><{$contact4[line].fax}></td>     <{* 输出数组第二维中下标为fax的元素值*}>
			<td><{$contact4[line].email}></td>   <{* 输出数组第二维中下标为email的元素值*}>
			<td><{$contact4[line].phone}></td>	 <{* 输出数组第二维中下标为phone的元素值*}>
		</tr>                             <{* 输出表格的行结束标记 *}>
	<{/section}>                              <{* section区域的结束标记 *}>
</table>
<!--测试四结束-->
</div>
<!--测试五开始-->
<div>
<{section name=customer loop=$custid}>
<hr>
  id: <{$custid[customer]}><br />
  name: <{$name[customer]}><br />
  address: <{$address[customer]}><br />
  <{section name=contact loop=$contact_type[customer]}>
    <{$contact_type[customer][contact]}>: <{$contact_info[customer][contact]}><br />
  <{/section}>
<{/section}> 
</div>
<!--测试五结束-->
	</body>
</html>

 

posted on 2014-05-03 17:21  lbsf  阅读(299)  评论(0)    收藏  举报

导航