smarty 学习记录

smarty模版是比较大众化的一个模版,在php开发过程中被不少开发者视为最友好的模版之一,学习smarty课程对于不少培训机构来讲也是列入了培训课程之一,那么不少方面就须要咱们学习了
一. 安装
首先打开网页http://smarty.php.net/download.php,下载最新版本的Smarty。解压下载的文件(目录结构还蛮复杂的)。例如:
(1) 我在根目录下创建了新的目录learn/,再在learn/里创建一个文件夹smarty/。将刚才解压缩出来的目录的libs/拷贝到smarty/里, 再在smarty/里新建templates目录,templates里新建cache/,templates/,templates_c/, config/,
(2) 新建一个模板文件:index.tpl,将此文件放在learn/smarty/templates/templates目录下,代码以下:
<!DOCTYPE HTML PUBLIC "-//W3C//DTDHTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<metahttp-equiv="Content-Type" c>
<title>Smarty</title>
</head>
<body>
{$hello}
</body>
</html>
新建index.php,将此文件放在learn/下:
<?php
//引用类文件
require 'smarty/libs/Smarty.class.php';
$smarty = new Smarty;
//设置各个目录的路径,这里是安装的重点
$smarty->template_dir ="smarty/templates/templates";
$smarty->compile_dir ="smarty/templates/templates_c";
$smarty->config_dir = "smarty/templates/config";
$smarty->cache_dir ="smarty/templates/cache";
//smarty模板有高速缓存的功能,若是这里是true的话即打开caching,可是会形成网页不当即更新的问题,固然也能够经过其余的办法解决
$smarty->caching = false;
$hello = "Hello World!";
//赋值
$smarty->assign("hello",$hello);
//引用模板文件
$smarty->display('index.tpl');
?>
(3) 执行index.php就能看到Hello World!了。
二. 赋值
在模板文件中须要替换的值用大括号{}括起来,值的前面还要加$号。例如{$hello}。这里能够是数组,好比{$hello.item1},{$hello.item2}…
而PHP源文件中只须要一个简单的函数assign(var , value)。
简单的例子:
*.tpl:
Hello,{$exp.name}!Good {$exp.time}
*.php:
$hello[name]= “Mr. Green”;
$hello[time]=”morning”;
$smarty->assign(“exp”,$hello);
output:
Hello,Mr.Green!Good morning
三. 引用
网站中的网页通常header和footer是能够共用的,因此只要在每一个tpl中引用它们就能够了。
示例:*.tpl:
{include file="header.tpl"}
{* body of template goes here *}
{include file="footer.tpl"}
四. 判断
模板文件中可使用if else等判断语句,便可以将一些逻辑程序放在模板里。"eq","ne", "neq", "gt", "lt","lte", "le", "gte" "ge","is even", "is odd", "is not even", "is notodd", "not", "mod", "div by", "evenby", "odd by","==","!=",">","<","<=",">="这些是if中能够用到的比较。看看就能知道什么意思吧。
示例:
{if $name eq"Fred"}
WelcomeSir.
{elseif $name eq"Wilma"}
WelcomeMa'am.
{else}
Welcome,whatever you are.
{/if}
五. 循环
在Smarty里使用循环遍历数组的方法是section,如何赋值遍历都是在模板中解决,php源文件中只要一个assign就能解决问题。
示例:
{* this examplewill print out all the values of the $custid array *}
{secti loop=$custid}
id: {$custid[customer]}<br>
{/section}
OUTPUT:
id: 1000<br>
id: 1001<br>
id: 1002<br>
六. 常见问题
Smarty将全部大括号{}里的东西都视为本身的逻辑程序,因而咱们在网页中想插入javascrīpt函数就须要literal的帮忙了,literal的功能就是忽略大括号{}。
示例:
{literal}
<scrīptlanguage=javascrīpt>
function isblank(field) {
if (field.value == '')
{ return false; }
else
{
document.loginform.submit();
return true;
}
}
</scrīpt>
{/literal}javascript

 

 


这篇文章主要介绍了smarty半小时快速上手入门教程,以实例的形式分析了smarty在实际使用过程当中的属性、方法及具体用法,须要的朋友能够参考下
 

本文讲述了smarty快速上手入门的方法,可让读者在半小时内快速掌握smarty的用法。分享给你们供你们参考。具体实现方法以下:php

1、smarty的程序设计部分:html

在smarty的模板设计部分我简单的把smarty在模板中的一些经常使用设置作了简单的介绍,这一节主要来介绍一下如何在smarty中开始咱们程序设计。下载Smarty文件放到大家站点中。java

index.php代码以下:mysql

 

复制代码代码以下:
<?php 
/** 

* @version $Id: index.php 
* @package 
* @author www.jb51.net 
* @action 显示实例程序 
*/ 
include_once("./Smarty/Smarty.class.php"); //包含smarty类文件

 

$smarty = new Smarty(); //创建smarty实例对象$smarty 
$smarty->templates("./templates"); //设置模板目录 
$smarty->templates_c("./templates_c"); //设置编译目录 
$smarty->cache("./cache"); //缓存目录 
$smarty->cache_lifetime = 0; //缓存时间 
$smarty->caching = true; //缓存方式linux

$smarty->left_delimiter = "{#"; 
$smarty->right_delimiter = "#}"; 
$smarty->assign("name", "zaocha"); //进行模板变量替换 
$smarty->display("index.htm"); //编译并显示位于./templates下的index.htm模板 
?>web


2、解释smarty的程序

 

咱们能够看到,smarty的程序部分实际就是符合php语言规范的一组代码,咱们依次来解释一下:sql

1:/**/语句:数据库

包含的部分为程序篇头注释。主要的内容应该为对程序的做用,版权与做者及编写时间作一个简单的介绍,这在smarty中不是必需的,但从程序的风格来说,这是一个好的风格。小程序

2:include_once语句:

它将安装到网站的smarty文件包含到当前文件中,注意包含的路径必定要写正确。

3:$smarty = new Smarty():

这一句新建一个Smarty对象$smarty,简单的一个对象的实例化。

4:$smarty->templates(""):

这一句指明$smarty对象使用tpl模板时的路径,它是一个目录,在没有这一句时,Smarty默认的模板路径为当前目录的templates目录,实际在写程序时,咱们要将这一句写明,这也是一种好的程序风格。

5:$smarty->templates_c(""):

这一句指明$smarty对象进行编译时的目录。在模板设计篇咱们已经知道Smarty是一种编译型模板语言,而这个目录,就是它编译模板的目录,要注意,若是站点位于linux服务器上,请确保

teamplates_c里定义的这个目录具备可写可读权限,默认状况下它的编译目录是当前目录下的templates_c,出于一样的理由咱们将其明确的写出来。

6:$smarty->left_delimiter与$smarty->right_delimiter:

指明在查找模板变量时的左右分割符。默认状况下为"{"与"}",但在实际中由于咱们要在模板中使用<script>,Script中的函数定义不免会使用{},虽然它有本身的解决办法,但习惯上咱们将它从新定义

为"{#"与"#}"或是"<!--{"与"}-->"或其它标志符,注意,若是在这里定义了左右分割符后,在模板文件中相应的要使每个变量使用与定义相同的符号,例如在这里指定为"<{"与"}>",htm模板中也要

相应的将{$name}变成<{$name}>,这样程序才能够正确的找到模板变量。

7:$smarty->cache("./cache"):

告诉Smarty输出的模板文件缓存的位置。上一篇咱们知道Smarty最大的优势在于它能够缓存,这里就是设置缓存的目录。默认状况下为当前目录下的cache目录,与templates_c目录至关,在linux系统中

咱们要确保它的可读可写性。

8:$smarty->cache_lifetime = 60 * 60 * 24:

这里将以秒为单位进行计算缓存有效的时间。第一次缓存时间到期时当Smarty的caching变量设置为true时缓存将被重建。当它的取值为-1时表示创建起的缓存从不过时,为0时表示在程序每次执行时缓

存老是被从新创建。上面的设置表示将cache_lifetime设置为一天。

9:$smarty->caching = 1:

这个属性告诉Smarty是否要进行缓存以及缓存的方式。它能够取3个值,0:Smarty默认值,表示不对模板进行缓存;1:表示Smarty将使用当前定义的cache_lifetime来决定是否结束cache;2:表示

Smarty将使用在cache被创建时使用cache_lifetime这个值。习惯上使用true与false来表示是否进行缓存。

10:$smarty->assign("name", "zaocha"):

该数的原型为assign(string varname, mixed var),varname为模板中使用的模板变量,var指出要将模板变量替换的变量名;其第二种原形为assign(mixed var),咱们要在后面的例子详细的讲解这个成员函数的使用方法,assign是Smarty的核心函数之一,全部对模板变量的替换都要使用它。

11:$smarty->display("index.tpl"):

该函数原形为display(string varname),做用为显示一个模板。简单的讲,它将分析处理过的模板显示出来,这里的模板文件不用加路径,只要使用一个文件名就能够了,它路径咱们已经在$smarty->templates(string path)中定义过了。

程序执行完后咱们能够打开当前目录下的templates_c与cache目录,就会发如今下边多出一些%%的目录,这些目录就是Smarty的编译与缓存目录,它由程序自动生成,不要直接对这些生成的文件进行修改。

以上我简单的把Smarty程序中的一些经常使用的基本元素介绍了一下,在后边的例子中你能够看到将它们将被屡次的使用。

3、模板说明

接下来介绍一个section循环块与foreach循环块,原本它应该属于模板部分,可是因为它们是smarty的精华所在,并且与smarty程序设计部分联系很是紧密,因此就在本节单独拿出来说一下。

1: foreach:用于循环简单数组,它是一个选择性的section循环,它的定义格式为:

 

复制代码代码以下:
{foreach from=$array item=array_id} 
{foreachelse} 
{/foreach}

其中,from 指出要循环的数组变量,item为要循环的变量名称,循环次数由from所指定的数组变量的个数所决定。{foreachelse}用来当程序中传递过来的数组为空时的处理,下面是一个简单的例子:

 

模板文件:

example.htm页面以下:

 

复制代码代码以下:
foreach 输出一个“二维关联数组”的数据:

 

{#foreach item=new from=$news#}

新闻编号:{#$new.id#}

新闻内容:{#$new.title#}

{#foreachelse#}
数据库中没有新闻输出!

{#/foreach#}

{foreach from=$newsArray item=newsID}
新闻编号:{$newsID}
新闻内容:{$newsTitle}
{foreachelse}
对不起,数据库中没有新闻输出!

{/foreach}


这是一个错误的不显示数据,本文作了更正。

 

程序文件:example.php以下:

 

复制代码代码以下:
<?php
/********************************************* 

* 文件名: example.php 
* 做 用: 显示实例程序2 
*********************************************/ 
include_once("./Smarty/Smarty.class.php"); 
$smarty = new Smarty(); 
$smarty->templates("./templates"); 
$smarty->templates_c("./templates_c"); 
$smarty->cache("./cache"); 
$smarty->cache_lifetime = 0; 
$smarty->caching = true; 
$smarty->left_delimiter = "{#"; 
$smarty->right_delimiter = "#}"; 
$array[] = array("newsID"=>1, "newsTitle"=>"第1条新闻"); 
$array[] = array("newsID"=>2, "newsTitle"=>"第2条新闻"); 
$array[] = array("newsID"=>3, "newsTitle"=>"第3条新闻"); 
$array[] = array("newsID"=>4, "newsTitle"=>"第4条新闻"); 
$array[] = array("newsID"=>5, "newsTitle"=>"第5条新闻"); 
$array[] = array("newsID"=>6, "newsTitle"=>"第6条新闻"); 
//这是一个二维关联数组 
$smarty->assign("newsArray", $array); 
//编译并显示位于./templates下的index.htm模板 
$smarty->display("example.htm"); 
?>

输入结果:example.php输出以下:

 

 

复制代码代码以下:
这里将输出一个数组:

 

新闻编号:1

新闻内容:第1条新闻

新闻编号:2

新闻内容:第2条新闻

新闻编号:3

新闻内容:第3条新闻

新闻编号:4

新闻内容:第4条新闻

新闻编号:5

新闻内容:第5条新闻

新闻编号:6

新闻内容:第6条新闻

 

foreach还能够用foreachelse来匹配,用foreachelse来表示当传递给foreach的数组为空值时程序要执行的操做,具体的使用方法,请参考手册的说明。

2. section:

section的产生是为解决foreach的不足的,与foreach同样,它用于设计模板内的循环块,它较为复杂,可极大程序上知足程序须要,因此在程序中我习惯使用它而不使用foreach,基本原形为:

 

复制代码代码以下:
{section name = name loop = $varName[, start = $start, step = $step, max = $max, show = true]}

 

参数解释以下:

name: section的名称,不用加$

$loop: 要循环的变量,在程序中要使用assign对这个变量进行操做。

$start: 开始循环的下标,循环下标默认由0开始

$step: 每次循环时下标的增数

$max: 最大循环下标

$show: boolean类型,决定是否对这个块进行显示,默认为true
这里有个名词须要说明:

循环下标:实际它的英文名称为index,是索引的意思,这里我将它译成"下标",主要是为了好理解。它表示在显示这个循环块时当前的循环索引,默认从0开始,受$start的影响,若是将$start设为5,它也将从5开始计数,在模板设计部分咱们使用过它,这是当前{section}的一个属性,调用方式为Smarty.section.sectionName.index,这里的sectionName指的是函数原型中的name属性。

{section}块具备的属性值,分别为:

1. index: 上边咱们介绍的"循环下标",默认为0

2. index_prev: 当前下标的前一个值,默认为-1

3. index_next: 当前下标的下一个值,默认为1

4. first: 是否为第一下循环

5. last: 是否为最后一个循环

6. iteration: 循环次数

7. rownum: 当前的行号,iteration的另外一个别名

8. loop: 最后一个循环号,可用在section块后统计section的循环次数

9. total: 循环次数,可用在section块后统计循环次数

10. show: 在函数的声明中有它,用于判断section是否显示

它们的具体属性你们能够参考手册,在程序中可灵活使用它的这些属性,模板部分我就使用过index属性,你们能够回过头去看看。

一样,{section}也能够配合使用{sectionelse},用来表示传入的数组变量为空时对模板进行的处理。

咱们把上边的那个例子使用{section}来替代{foreach}来实现现样的功能,注意,在这个例子中我只将tpl模板中的{foreach}用{section}来实现,php程序文件中没有任何改动,同时加了{sectionelse}处理块:

example.tpl模板文件以下:

 

复制代码代码以下:
这里将输出一个数组:

 

{section name=loop loop=$News} 
新闻编号:{$News[loop].newsID} 
新闻标题:{$News[loop].newsTitle} 
{sectionelse} 
对不起,没有任何新闻输入! 
{/section}

 

example.php文件以下:

 

复制代码代码以下:
<?php
/*********************************************

 

*

* 文件名: example7.php

* 做 用: 显示实例程序2

*********************************************/

include_once("./comm/Smarty.class.php");

$smarty = new Smarty();

$smarty->templates("./templates");

$smarty->templates_c("./templates_c");

$smarty->cache("./cache");

$smarty->cache_lifetime = 0;

$smarty->caching = true;

$smarty->left_delimiter = "{";

$smarty->right_delimiter = "}";

$array[] = array("newsID"=>1, "newsTitle"=>"第1条新闻");

$array[] = array("newsID"=>2, "newsTitle"=>"第2条新闻");

$array[] = array("newsID"=>3, "newsTitle"=>"第3条新闻");

$array[] = array("newsID"=>4, "newsTitle"=>"第4条新闻");

$array[] = array("newsID"=>5, "newsTitle"=>"第5条新闻");

$array[] = array("newsID"=>6, "newsTitle"=>"第6条新闻");

$smarty->assign("newsArray", $array);

//编译并显示位于./templates下的index.tpl模板

$smarty->display("example.tpl");

?>


example.php 输出文件以下:

 

 

复制代码代码以下:
这里将输出一个数组:

 

新闻编号:1

新闻内容:第1条新闻

新闻编号:2

新闻内容:第2条新闻

新闻编号:3

新闻内容:第3条新闻

新闻编号:4

新闻内容:第4条新闻

新闻编号:5

新闻内容:第5条新闻

新闻编号:6

新闻内容:第6条新闻


这里的{section}块的对于变量的命名方式感受有些别扭,不过不要紧,你只要记住模板变量使用:

 

$loopName[name].var这种模式就好了,loopName为loop处赋予的变量名,[name]为name处赋予的字符串,.后为为你要在程序数组中设定要与值相对应的下标名称就好了。

好了,本文关于smarty程序设计学习指南就写到这里,对于通常的应用,这些知识已经够用了,其它的一些高级技巧你们请参看手册中的例子,此外相关的还有Smarty在实际应用中的例子,以php内置的mysql语句,phplib中的DB类,ADODB,Pear中DB类等等。感兴趣的朋友能够关注一下相关内容。

但愿本文所述对你们的PHP程序设计有所帮助。

您可能感兴趣的文章:

 



smarty模板引擎基础知识入门

做者:诗未冷 字体:[增长 减少] 类型:转载 时间:2015-03-30 我要评论

这篇文章主要介绍了smarty模板引擎基础知识入门,较为详细的分析了smarty的基本概念并实例分析了相关的基本用法,具备必定参考借鉴价值,须要的朋友能够参考下
 

本文实例讲述了smarty模板引擎基础知识。分享给你们供你们参考。具体以下:

1、基本概念

1.什么是mvc?
mvc是一种开发模式,核心思想是:数据的输入、数据的处理、数据显示的强制分离。
2.什么是smarty?
smarty是一个php的模板引擎。更明确的来讲,它能够帮助开发者更好的分离程序逻辑和页面显示。

3.smarty运行原理
模板文件,就是一个显示数据的模板,其中须要显示的数据用占位符代替。
smarty运行时,会读取模板文件,将模板文件中的占位符替换成真正的数据,并输出一个处理后的php文件,交由服务器运行。

2、本身写一个smarty模板

为了更好的理解smarty模板,如今本身先写一个本身的smarty模板-minismarty,让本身更加深刻的了解smarty运行原理。

1.新建项目minismarty
新建模板文件路径:templates
新建模板文件被编译后的文件路径:templates_c
新建模板文件:intro.tpl
新建运行的文件:index.php
新建本身的smarty,即处理模板的文件:cls_MiniSmarty.php

2.编写index.php文件

<?php 
  require_once './cls_MiniSmarty.php';
  $miniSmarty = new MiniSmarty();
  //传递数据
  $miniSmarty->assign("title","hello minismarty!");
  $miniSmarty->assign("content","<font color='red'>this is content!</font>");
  //传递数据到哪一个页面显示
  $miniSmarty->display("intro.tpl");
?>

3.编写intro.tpl文件

<!--这是个模板文件--> 
<html> 
<head> 
<meta http-equiv="Content-Language" content="en" />
<meta name="GENERATOR" content="PHPEclipse 1.0" />
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>{$title}</title>
</head>
<body bgcolor="#FFFFFF" text="#000000" link="#FF9966" vlink="#FF9966" alink="#FFCC99">
{$content}
</body>
</html>

这里面的内容是用占位符的形式,smarty的做用就是将占位符的内容替换成真正的数据。
这样就能够实现模板文件和数据文件强制分离,经过smarty进行数据的传递。

4.编写cls_MiniSmarty.php文件

<?php 
/** 
 * 
 * 本来是经过smarty模板引擎给模板提供数据的 
 * 如今本身模仿写一个模板,给模板提供数据的类 
 * smarty运行时,读取模板文件,将模板文件替换成可运行的php文件
 * 服务器真正运行的文件是处理后的文件
 */ 
class MiniSmarty { 
  //模板文件路径 
  var $template_dir = "./templates/"; 
  //模板文件被替换后的文件路径 
  var $templates_c_dir = "./templates_c/"; 
  //存放变量值 
  var $tpl_vars = array (); 
  //主要模拟2个方法 
  /** 
   * 添加数据 
   * 参数1:键 
   * 参数2:值,默认为null 
   */ 
  function assign($tpl_var, $var = null) { 
    if ($tpl_var != '') { 
      $this->tpl_vars[$tpl_var] = $var; //将数据添加到数组中 
    } 
  } 
  /** 
   * 显示数据 
   * 参数1:显示到哪一个模板文件中 
   */ 
  function display($tpl_file) { 
    //得到模板文件的路径 
    $tpl_file_path = $this->template_dir . $tpl_file; 
    //得到模板文件被编译后的文件路径 
    $compile_file_path = $this->templates_c_dir . "com_" . $tpl_file . ".php"; 
    //判断文件是否存在 
    if (!file_exists($tpl_file_path)) { 
      return false; 
    } 
    //不用每次都生成编译文件,只有编译文件不存在或者模板文件被修改了才生成新的编译文件 
    //至关于缓存了编译文件 
    //filemtime函数:得到文件的生成时间 
    if (!file_exists($compile_file_path) || filemtime($tpl_file_path) > filemtime($compile_file_path)) { 
      //读取模板文件的内容 
      $fpl_file_content = file_get_contents($tpl_file_path); 
      $newStr = myReplace($fpl_file_content); 
      //将替换后的字符串生成新的文件,也就是编译后的文件 
      file_put_contents($compile_file_path, $newStr); 
    } 
    //引入编译后的文件 
    include $compile_file_path; 
  } 
  /** 
   * 对模板文件中的内容进行替换,得到新的字符串 
   */ 
  function myReplace($fpl_file_content) { 
    $pattern = array ( 
      '/\{\s*\$([a-zA-Z_][a-zA-Z0-9_]*)\s*\}/i' 
    ); 
    $replace = array ( 
      '<?php echo $this->tpl_vars["${1}"] ?>' 
    ); 
    $newStr = preg_replace($pattern, $replace, $fpl_file_content); 
    return $newStr; 
  } 
} 
?>

preg_replace方法介绍:
参数1:替换的规则
参数2:替换成的内容
参数3:替换操做的内容

5.运行结果

标题和内容都显示出来了:

结论:

真正运行的文件,既不是index.php,也不是intro.php,而是两者经过smarty做用后的文件:
com_intro.tpl.php。这个文件中数据来源于index.php,显示的布局来自intro.tpl,中间的桥梁是smarty。
smarty的做用是接受数据、填充数据(替换模板中的占位符)、并加载替换后的文件。

3、讲解smarty使用细节

1.如何配置smarty?

解压后,将libs文件夹拷贝到项目目录下便可,而后再建立2个文件夹templates和templates_c,分别放模板文件和模板编译后文件。

2.使用smarty注意事项

①替换变量的标示符。
由于默认的表示符是{}这个和style样式中的{}发生冲突,因此须要修改一下默认的标识符,通常修改成:{<>}
②修改标识符的方法。
方法一:直接修改smarty类源码:不推荐。
方法二:使用smarty提供的方法进行修改。

$smarty->left_delimiter="{<";
$smarty->right_delimiter=">}";

③smarty的一些基本配置

$smarty->template_dir="./templates";//模板路径
$smarty->compile_dir="./templates_c";//编译路径
$smarty->caching=false;  //是否使用缓存
$smarty->cache_dir="./smarty_cache";//若是使用缓存的话:缓存的路径

3.smarty模板技术分配变量的细节问题

一句话:能够分配php支持的各类数据。
php基本数据:int double string bool
复合数据类型:array object
特殊数据类型:resource null

但愿本文所述对你们的php程序设计有所帮助。

 



菜鸟学PHP之Smarty入门

做者: 字体:[增长 减少] 类型:转载 时间:2007-01-04 我要评论

 
 

刚开始接触模版引擎的 PHP 设计师,听到 Smarty 时,都会以为很难。其实笔者也不例外,碰都不敢碰一下。可是后来在剖析 XOOPS 的程序架构时,开始发现 Smarty 其实并不难。只要将 Smarty 基础功练好,在通常应用上就已经至关足够了。固然基础能打好,后面的进阶应用也就不用怕了。 这篇文章的主要用意并不是要深刻探讨 Smarty 的使用,这在官方使用说明中都已经写得很完整了。笔者仅在此写下一些本身使用上的心得,让想要了解 Smarty 却不得其门而入的朋友,能够从中获得一些启示。就由于这篇文章的内容不是很是深刻,会使用 Smarty 的朋友们可能会以为简单了点。 目前本文已经第三次修订了,本想多加一些料进来;不过碍于时间的关系,不少 Smarty 的进阶技巧笔者并无研究得很透彻,因此也不敢拿出来现眼,但笔者相信这篇文章应该可以知足大多数想学习 Smarty 的初学者了。固然本文有谬误的地方也欢迎告知,笔者会在下一次的修订中更正的。 Smarty介绍 什么是模版引擎 不知道从何时开始,有人开始对 HTML 内嵌入 Server Script 以为不太满意。然而不管是微软的 ASP 或是开放源码的 PHP,都是属于内嵌 Server Script 的网页伺服端语言。所以也就有人想到,若是能把程序应用逻辑 (或称商业应用逻辑) 与网页呈现 (Layout) 逻辑分离的话,是否是会比较好呢? 其实这个问题早就存在已久,从交互式网页开始风行时,不管是 ASP 或是 PHP 的使用者都是身兼程序开发者与视觉设计师两种身份。但是一般这些使用者不是程序强就是美工强,若是要二者同时兼顾,那可得死掉很多脑细胞... 因此模版引擎就应运而生啦!模版引擎的目的,就是要达到上述提到的逻辑分离的功能。它能让程序开发者专一于资料的控制或是功能的达成;而视觉设计师则可专一于网页排版,让网页看起来更具备专业感!所以模版引擎很适合公司的网站开发团队使用,使每一个人都能发挥其专长! 就笔者接触过的模版引擎来讲,依资料呈现方式大概分红:需搭配程序处理的模版引擎和彻底由模版自己自行决定的模版引擎两种形式。 在需搭配程序处理的模版引擎中,程序开发者必需要负责变量的呈现逻辑,也就是说他必须把变量的内容在输出到模版前先处理好,才能作 assign 的工做。换句话说,程序开发者仍是得多写一些程序来决定变量呈现的风貌。而彻底由模版自己自行决定的模版引擎,它容许变量直接 assign 到模版中,让视觉设计师在设计模版时再决定变量要如何呈现。所以它就可能会有另外一套属于本身的模版程序语法 (如 Smarty) ,以方便控制变量的呈现。但这样一来,视觉设计师也得学习如何使用模版语言。 模版引擎的运做原理,首先咱们先看看如下的运行图: 通常的模版引擎 (如 PHPLib) 都是在创建模版对象时取得要解析的模版,而后把变量套入后,透过 parse() 这个方法来解析模版,最后再将网页输出。 对 Smarty 的使用者来讲,程序里也不须要作任何 parse 的动做了,这些 Smarty 自动会帮咱们作。并且已经编译过的网页,若是模版没有变更的话, Smarty 就自动跳过编译的动做,直接执行编译过的网页,以节省编译的时间。 使用Smarty的一些概念 在通常模版引擎中,咱们常看到区域的观念,所谓区块大概都会长成这样: <!-- START : Block name --> 区域内容 <!-- END : Block name --> 这些区块大部份都会在 PHP 程序中以 if 或 for, while 来控制它们的显示状态,虽然模版看起来简洁多了,但只要一换了显示方式不一样的模版, PHP 程序势必要再改一次! 在 Smarty 中,一切以变量为主,全部的呈现逻辑都让模版自行控制。由于 Smarty 会有本身的模版语言,因此无论是区块是否要显示仍是要重复,都是用 Smarty 的模版语法 (if, foreach, section) 搭配变量内容做呈现。这样一来感受上好象模版变得有点复杂,但好处是只要规划得当, PHP 程序一行都没必要改。 由上面的说明,咱们能够知道使用Smarty 要掌握一个原则:将程序应用逻辑与网页呈现逻辑明确地分离。就是说 PHP 程序里不要有太多的 HTML 码。程序中只要决定好那些变量要塞到模版里,让模版本身决定该如何呈现这些变量 (甚至不出现也行) 。 Smarty的基础 安装Smarty 首先,咱们先决定程序放置的位置。 Windows下可能会相似这样的位置:「 d:appservwebdemo 」。 Linux下可能会相似这样的位置:「 /home/jaceju/public_html/ 」。 到Smarty的官方网站下载最新的Smarty套件:http://smarty.php.net。 解开 Smarty 2.6.0 后,会看到不少档案,其中有个 libs 资料夹。在 libs 中应该会有 3 个 class.php 檔 + 1 个 debug.tpl + 1 个 plugin 资料夹 + 1 个 core 资料夹。而后直接将 libs 复制到您的程序主资料夹下,再改名为 class 就能够了。就这样?没错!这种安装法比较简单,适合通常没有本身主机的使用者。 至于 Smarty 官方手册中为何要介绍一些比较复杂的安装方式呢?基本上依照官方的方式安装,能够只在主机安装一次,而后提供给该主机下全部设计者开发不一样程序时直接引用,而不会重复安装太多的 Smarty 复本。而笔者所提供的方式则是适合要把程序带过来移过去的程序开发者使用,这样不用烦恼主机有没有安装 Smarty 。 程序的资料夹设定 以笔者在Windows安装Appserv为例,程序的主资料夹是「d:appservwebdemo」。安装好Smarty后,咱们在主资料夹下再创建这样的资料夹: 在 Linux 底下,请记得将 templates_c 的权限变动为 777 。Windows 下则将其只读取消。 第一个用Smarty写的小程序 咱们先设定 Smarty 的路径,请将如下这个档案命名为 main.php ,并放置到主资料夹下: main.php: <?php  include "class/Smarty.class.php";  define(@#__SITE_ROOT@#, @#d:/appserv/web/demo@#); // 最后没有斜线  $tpl = new Smarty();  $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 = @#}>@#;  ?>  照上面方式设定的用意在于,程序若是要移植到其它地方,只要改 __SITE_ROOT 就能够啦。 (这里是参考 XOOPS 的 ) Smarty 的模版路径设定好后,程序会依照这个路径来抓全部模版的相对位置 (范例中是 @#d:/appserv/web/demo/templates/@# ) 。而后咱们用 display() 这个 Smarty 方法来显示咱们的模版。 接下来咱们在 templates 资料夹下放置一个 test.htm:(扩展名叫什么都无所谓,但便于视觉设计师开发,笔者都仍是以 .htm 为主。) templates/test.htm: <html>  <head>  <meta http-equiv="Content-Type" content="text/html; charset=big5">  <title><{$title}></title>  </head>  <body>  <{$content}>  </body>  </html>  如今咱们要将上面的模版显示出来,并将网页标题 ($title) 与内容 ($content) 更换,请将如下档案内容命名为 test.php ,并放置在主资料夹下: test.php: <?php  require "main.php";  $tpl->assign("title", "测试用的网页标题");  $tpl->assign("content", "测试用的网页内容");  // 上面两行也能够用这行代替  // $tpl->assign(array("title" => "测试用的网页标题", "content" => "测试用的网页内容"));  $tpl->display(@#test.htm@#);  ?>  请打开浏览器,输入 http://localhost/demo/test.php 试试看(依您的环境决定网址),应该会看到如下的画面: 再到 templates_c 底下,咱们会看到一个奇怪的资料夹 (%%179) ,再点选下去也是一个奇怪的资料夹 (%%1798044067) ,而其中有一个档案: templates_c/%%179/%%1798044067/test.htm.php: <?php /* Smarty version 2.6.0, created on 2003-12-15 22:19:45 compiled from test.htm */ ?>  <html>  <head>  <meta http-equiv="Content-Type" content="text/html; charset=big5">  <title><?php echo $this->_tpl_vars[@#title@#]; ?></title>  </head>  <body>  <?php echo $this->_tpl_vars[@#content@#]; ?>  </body>  </html>  没错,这就是 Smarty 编译过的档案。它将咱们在模版中的变量转换成了 PHP 的语法来执行,下次再读取一样的内容时, Smarty 就会直接抓取这个档案来执行了。 最后咱们整理一下整个 Smarty 程序撰写步骤: Step 1. 加载 Smarty 模版引擎。 Step 2. 创建 Smarty 对象。 Step 3. 设定 Smarty 对象的参数。 Step 4. 在程序中处理变量后,再用 Smarty 的 assign 方法将变量置入模版里。 Step 5. 利用 Smarty 的 display 方法将网页秀出。 如何安排你的程序架构 上面咱们看到除了 Smarty 所须要的资料夹外 (class 、 configs 、 templates 、 templates_c) ,还有两个资料夹: includes 、 modules 。其实这是笔者模仿 XOOPS 的架构所创建出来的,由于 XOOPS 是笔者所接触到的程序中,少数使用 Smarty 模版引擎的架站程序。所谓西瓜偎大边,笔者这样的程序架构虽没有 XOOPS 的百分之一强,但至少给人看时还有 XOOPS 撑腰。 includes 这个资料夹主要是用来放置一些 function 、 sql 檔,这样在 main.php 就能够将它们引入了,以下: main.php: <?php  include "class/Smarty.class.php";  define(@#__SITE_ROOT@#, @#d:/appserv/web/demo@#); // 最后没有斜线  // 以 main.php 的位置为基准  require_once "includes/functions.php";  require_once "includes/include.php";  $tpl = new Smarty();  $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 = @#}>@#;  ?>  modules 这个资料夹则是用来放置程序模块的,如此一来便不会把程序丢获得处都是,总体架构一目了然。上面咱们也提到 main.php ,这是整个程序的主要核心,不管是常数定义、外部程序加载、共享变量创建等,都是在这里开始的。因此以后的模块都只要将这个档案包含进来就能够啦。所以在程序流程规划期间,就必须好好构思 main.php 中应该要放那些东西;固然利用 include 或 require 指令,把每一个环节清楚分离是再好不过了。 在上节提到的 Smarty 程序 5 步骤, main.php 就会帮咱们先将前 3 个步骤作好,后面的模块程序只要作后面两个步骤就能够了。 从变量开始 如何使用变量 从上一章范例中,咱们能够清楚地看到咱们利用 <{ 及 }> 这两个标示符号将变量包起来。预设的标示符号为 { 及 } ,但为了中文冲码及 javascript 的关系,所以笔者仍是模仿 XOOPS ,将标示符号换掉。变量的命名方式和 PHP 的变量命名方式是如出一辙的,前面也有个 $ 字号 (这和通常的模版引擎不一样)。标示符号就有点像是 PHP 中的 <?php 及 ?>  (事实上它们的确会被替换成这个) ,因此如下的模版变量写法都是可行的: 1. <{$var}> 2. <{ $var }> <!-- 和变量之间有空格 --> 3. <{$var }> <!-- 启始的标示符号和结束的标示符号不在同一行 --> 在 Smarty 里,变量预设是全域的,也就是说你只要指定一次就行了。指定两次以上的话,变量内容会以最后指定的为主。就算咱们在主模版中加载了外部的子模版,子模版中一样的变量同样也会被替代,这样咱们就不用再针对子模版再作一次解析的动做。 而在 PHP 程序中,咱们用 Smarty 的 assign 来将变量置放到模版中。 assign 的用法官方手册中已经写得不少了,用法就如同上一节的范例所示。不过在重复区块时,咱们就必须将变量作一些手脚后,才能将变量 assign 到模版中,这在下一章再提。 修饰你的变量 上面咱们提到 Smarty 变量呈现的风貌是由模版自行决定的,因此 Smarty 提供了许多修饰变量的函式。使用的方法以下: <{变量|修饰函式}> <!-- 当修饰函式没有参数时 --> <{变量|修饰函式:"参数(非必要,视函式而定)"}> <!-- 当修饰函式有参数时 --> 范例以下: <{$var|nl2br}> <!-- 将变量中的换行字符换成 <br /> --> <{$var|string_format:"%02d"}> <!-- 将变量格式化 --> 好,那为何要让模版自行决定变量呈现的风貌?先看看底下的 HTML ,这是某个购物车结账的部份画面。<input name="total" type="hidden" value="21000" /> 总金额:21,000 元 通常模版引擎的模版可能会这样写: <input name="total" type="hidden" value="{total}" /> 总金额:{format_total} 元 它们的 PHP 程序中要这样写: <?php  $total = 21000;  $tpl->assign("total", $total);  $tpl->assign("format_total", number_format($total));  ?>  而 Smarty 的模版就能够这样写: (number_format 修饰函式请到Smarty 官方网页下载) <input name="total" type="hidden" value="<{$total}>" /> 总金额:<{$total|number_format:""}> 元 Smarty 的 PHP 程序中只要这样写: <?php  $total = 21000;  $tpl->assign("total", $total);  ?>  因此在 Smarty 中咱们只要指定一次变量,剩下的交给模版自行决定便可。这样了解了吗?这就是让模版自行决定变量呈现风貌的好处! 控制模版的内容 重复的区块 在 Smarty 样板中,咱们要重复一个区块有两种方式: foreach 及 section 。而在程序中咱们则要 assign 一个数组,这个数组中能够包含数组数组。就像下面这个例子: 首先咱们来看 PHP 程序是如何写的: test2.php: <?php  require "main.php";  $array1 = array(1 => "苹果", 2 => "菠萝", 3 => "香蕉", 4 => "芭乐");  $tpl->assign("array1", $array1);  $array2 = array(  array("index1" => "data1-1", "index2" => "data1-2", "index3" => "data1-3"),  array("index1" => "data2-1", "index2" => "data2-2", "index3" => "data2-3"),  array("index1" => "data3-1", "index2" => "data3-2", "index3" => "data3-3"),  array("index1" => "data4-1", "index2" => "data4-2", "index3" => "data4-3"),  array("index1" => "data5-1", "index2" => "data5-2", "index3" => "data5-3"));  $tpl->assign("array2", $array2);  $tpl->display("test2.htm");  ?>  而模版的写法以下: templates/test2.htm: <html>  <head>  <meta http-equiv="Content-Type" content="text/html; charset=big5">  <title>测试重复区块</title>  </head>  <body>  <pre>  利用 foreach 来呈现 array1  <{foreach item=item1 from=$array1}>  <{$item1}>  <{/foreach}>  利用 section 来呈现 array1  <{section name=sec1 loop=$array1}>  <{$array1[sec1]}>  <{/section}>  利用 foreach 来呈现 array2  <{foreach item=index2 from=$array2}>  <{foreach key=key2 item=item2 from=$index2}>  <{$key2}>: <{$item2}>  <{/foreach}>  <{/foreach}>  利用 section 来呈现 array1  <{section name=sec2 loop=$array2}>  index1: <{$array2[sec2].index1}>  index2: <{$array2[sec2].index2}>  index3: <{$array2[sec2].index3}>  <{/section}>  </pre>  </body>  </html>  执行上例后,咱们发现无论是 foreach 或 section 两个执行结果是同样的。那么二者到底有何不一样呢? 第一个差异很明显,就是foreach 要以巢状处理的方式来呈现咱们所 assign 的两层数组变量,而 section 则以「主数组[循环名称].子数组索引」便可将整个数组呈现出来。由此可知, Smarty 在模版中的 foreach 和 PHP 中的 foreach 是同样的;而 section 则是 Smarty 为了处理如上列的数组变量所发展出来的叙述。固然 section 的功能还不仅如此,除了下一节所谈到的巢状资料呈现外,官方手册中也提供了好几个 section 的应用范例。 不过要注意的是,丢给 section 的数组索引必须是从 0 开始的正整数,即 0, 1, 2, 3, ...。若是您的数组索引不是从 0 开始的正整数,那么就得改用 foreach 来呈现您的资料。您能够参考官方讨论区中的此篇讨论,其中探讨了 section 和 foreach 的用法。 巢状资料的呈现 模版引擎里最使人伤脑筋的大概就是巢状资料的呈现吧,许多著名的模版引擎都会特地强调这点,不过这对 Smarty 来讲倒是小儿科。 最多见到的巢状资料,就算论譠程序中的讨论主题区吧。假设要呈现的结果以下: 公告区 站务公告 文学专区 好书介绍 奇文共赏 计算机专区 硬件外围 软件讨论 程序中咱们先以静态资料为例: test3.php: <?php  require "main.php";  $forum = array(  array("category_id" => 1, "category_name" => "公告区",  "topic" => array(  array("topic_id" => 1, "topic_name" => "站务公告")  )  ),  array("category_id" => 2, "category_name" => "文学专区",  "topic" => array(  array("topic_id" => 2, "topic_name" => "好书介绍"),  array("topic_id" => 3, "topic_name" => "奇文共赏")  )  ),  array("category_id" => 3, "category_name" => "计算机专区",  "topic" => array(  array("topic_id" => 4, "topic_name" => "硬件外围"),  array("topic_id" => 5, "topic_name" => "软件讨论")  )  )  );  $tpl->assign("forum", $forum);  $tpl->display("test3.htm");  ?>  模版的写法以下: templates/test3.htm: <html>  <head>  <title>巢状循环测试</title>  </head>  <body>  <table width="200" border="0" align="center" cellpadding="3" cellspacing="0">  <{section name=sec1 loop=$forum}>  <tr>  <td colspan="2"><{$forum[sec1].category_name}></td>  </tr>  <{section name=sec2 loop=$forum[sec1].topic}>  <tr>  <td width="25"> </td>  <td width="164"><{$forum[sec1].topic[sec2].topic_name}></td>  </tr>  <{/section}>  <{/section}>  </table>  </body>  </html>  执行的结果就像笔者举的例子同样。 所以呢,在程序中咱们只要想办法把所要重复值一层一层的塞到数组中,再利用 <{第一层数组[循环1].第二层数组[循环2].第三层数组[循环3]. ... .数组索引}> 这样的方式来显示每个巢状循环中的值。至于用什么方法呢?下一节使用数据库时咱们再提。 转换数据库中的资料 上面提到如何显示巢状循环,而实际上应用时咱们的资料多是从数据库中抓取出来的,因此咱们就得想办法把数据库的资料变成上述的多重数组的形式。这里笔者用一个 DB 类别来抓取数据库中的资料,您能够自行用您喜欢的方法。 咱们只修改 PHP 程序,模版仍是上面那个 (这就是模版引擎的好处~),其中 $db 这个对象假设已经在 main.php 中创建好了,并且抓出来的资料就是上面的例子。 test3.php: <?php  require "main.php";  // 先创建第一层数组  $category = array();  $db->setSQL($SQL1, @#CATEGORY@#);  if (!$db->query(@#CATEGORY@#)) die($db->error());  // 抓取第一层循环的资料  while ($item_category = $db->fetchAssoc(@#CATEGORY@#))  {  // 创建第二层数组  $topic = array();  $db->setSQL(sprintf($SQL2, $item_category[@#category_id@#]), @#TOPIC@#);  if (!$db->query(@#TOPIC@#)) die($db->error());  // 抓取第二层循环的资料  while ($item_topic = $db->fetchAssoc(@#TOPIC@#))  {  // 把抓取的数据推入第二层数组中  array_push($topic, $item_topic);  }  // 把第二层数组指定为第一层数组所抓取的数据中的一个成员  $item_category[@#topic@#] = $topic;  // 把第一层数据推入第一层数组中  array_push($category, $item_category);  }  $tpl->assign("forum", $category);  $tpl->display("test3.htm");  ?>  在数据库抓取一笔资料后,咱们获得的是一个包含该笔数据的数组。透过 while 叙述及 array_push 函式,咱们将数据库中的资料一笔一笔塞到数组里。若是您只用到单层循环,就把第二层循环 (红色的部份) 去掉便可。 决定内容是否显示 要决定是否显示内容,咱们可使用 if 这个语法来作选择。例如若是使用者已经登入的话,咱们的模版就能够这样写: <{if $is_login == true}> 显示使用者操做选单 <{else}> 显示输入账号和密码的窗体 <{/if}> 要注意的是,「==」号两边必定要各留至少一个空格符,不然 Smarty 会没法解析。 if 语法通常的应用能够参照官方使用说明,因此笔者在这里就不详加介绍了。不过笔者发现了一个有趣的应用:经常会看到程序里要产生这样的一个表格: (数字表明的是资料集的顺序) 1 2 3 4 5 6 7 8 这个笔者称之为「横向重复表格」。它的特点和传统的纵向重复不一样,前几节咱们看到的重复表格都是从上而下,一列只有一笔资料。而横向重复表格则能够横向地在一列中产生 n 笔资料后,再换下一列,直到整个循环结束。要达到这样的功能,最简单的方式只须要 section 和 if 搭配便可。 咱们来看看下面这个例子: test4.php: <?php  require "main.php";  $my_array = array(  array("value" => "0"),  array("value" => "1"),  array("value" => "2"),  array("value" => "3"),  array("value" => "4"),  array("value" => "5"),  array("value" => "6"),  array("value" => "7"),  array("value" => "8"),  array("value" => "9"));  $tpl->assign("my_array", $my_array);  $tpl->display(@#test4.htm@#);  ?>  模版的写法以下: templates/test4.htm: <html>  <head>  <title>横向重复表格测试</title>  </head>  <body>  <table width="500" border="1" cellspacing="0" cellpadding="3">  <tr>  <{section name=sec1 loop=$my_array}>  <td><{$my_array[sec1].value}></td>  <{if $smarty.section.sec1.rownum is div by 2}>  </tr>  <tr>  <{/if}>  <{/section}>  </tr>  </table>  </body>  </html>  重点在于 $smarty.section.sec1.rownum 这个 Smarty 变量,在 section 循环中这个变量会取得从 1 开始的索引值,因此当 rownum 能被 2 除尽时,就输出 </tr><tr> 使表格换列 (注意!是 </tr> 在前面<tr> 在后面) 。所以数字 2 就是咱们在一列中想要呈现的资料笔数。各位能够由此去变化其它不一样的呈现方式。 加载外部内容 咱们能够在模版内加载 PHP 程序代码或是另外一个子模版,分别是使用 include_php 及 include 这两个 Smarty 模版语法; include_php 笔者较少用,使用方式能够查询官方手册,这里再也不叙述。 在使用 include 时,咱们能够预先加载子模版,或是动态加载子模版。预先加载一般使用在有共同的文件标头及版权宣告;而动态加载则能够用在统一的框架页,而进一步达到如 Winamp 般可换 Skin 。固然这两种咱们也能够混用,视情况而定。 咱们来看看下面这个例子: test5.php: <?php  require "main.php";  $tpl->assign("title", "Include 测试");  $tpl->assign("content", "这是模版 2 中的变量");  $tpl->assign("dyn_page", "test5_3.htm");  $tpl->display(@#test5_1.htm@#);  ?>  模版 1 的写法以下: templates/test5_1.htm: <html>  <head>  <meta http-equiv="Content-Type" content="text/html; charset=big5">  <title><{$title}></title>  </head>  <body>  <{include file="test5_2.htm"}><br />  <{include file=$dyn_page}>  <{include file="test5_4.htm" custom_var="自订变量的内容"}>  </body>  </html>  模版 2 的写法以下: templates/test5_2.htm: <{$content}> 模版 3 的写法以下: templates/test5_3.htm: 这是模版 3 的内容 模版 4 的写法以下: templates/test5_4.htm: <{$custom_var}> 这里注意几个重点:1. 模版的位置都是以先前定义的 template_dir 为基准;2. 全部 include 进来的子模版中,其变量也会被解译。;3. include 中能够用「变量名称=变量内容」来指定引含进来的模版中所包含的变量,如同上面模版 4 的作法。

相关文章
相关标签/搜索