`
ythzjk
  • 浏览: 75729 次
  • 性别: Icon_minigender_1
  • 来自: 上海
最近访客 更多访客>>
社区版块
存档分类
最新评论

用 Smarty 分离 PHP 应用程序中的形式与功能

阅读更多

用 Smarty 分离 PHP 应用程序中的形式与功能

使用智能模板引擎分离 Web 页面标记与底层设计逻辑

developerWorks
文档选项
将打印机的版面设置成横向打印模式

打印本页

将此页作为电子邮件发送

将此页作为电子邮件发送

样例代码


级别: 中级

Martin Streicher (martin.streicher@linux-mag.com), 主编, Linux Magazine

2007 年 9 月 06 日

随意混用 PHP 与其他 Web 页面标记将导致程序逻辑、HTML、层叠样式表(Cascading Style Sheets,CSS)和 JavaScript 处于混乱状态,使维护成为一项艰巨的任务。Smarty 模板引擎可以将形式与功能分离。

PHP Web 应用程序易于上手。PHP 语言的语法整洁且易于掌握。可以将 PHP 与 HTML、JavaScript 和 CSS 直接混用以快速生成可视结果。而且,把 PHP 应用程序部署到您自己的 Web 服务器或托管服务中只是小菜一碟。

但是混用 PHP 与其他页面标记也是一项责任。PHP 代码通常是含有程序逻辑、结构化查询语言(Structured Query Language,SQL)查询、函数、类、开发人员注释、HTML、CSS 样式和脚本的复杂 web(不是开玩笑)。更糟糕的是,把内容从 PHP、echo 发送到输出缓冲区有很多种方法。维护这样混乱的页面十分费力。对代码或标记做出无关紧要的更改会带来严重破坏,并且增强页面可能需要设计人员与程序员的共同努力。使用 PHP,形式(页面的布局)及功能(页面的目的和构造)将被混在一起。

在理想情况下,形式与功能是相互独立的。例如,CSS 和 HTML 一定应该如此。CSS 是形式,而 HTML 是功能。在使用 PHP 的情况下,如果页面标记和代码能够分离将是十分理想的。代码将处理输入,制定决策并生成显示数据,而标记将期待获得数据并提供所需的支架以渲染信息。

例如,主页的标记可能留下一个 “填空” (fill in the blank) 以供用户登录,以及其他占位符以供保存用户的图像和重要信息。此模板 —— 这样命名是因为它将提供页面显示的模式 —— 只面向设计人员,设计人员将控制页面的整体外观并留下名称、图片和其他数据的占位符。代码只是为占位符提供数据。开发人员的任务仍然主要集中在计算上。

当然,形式与功能必须协作。如果模板期望获得以美元为单位的金额,则代码不应当提供 URL。如果模板期望获得对象,则代码不应当提供列表。因此,模板系统必须将表单与函数分离,但还必须在两者之间建立联系。

最流行的 Web 应用程序编程语言(Perl、Python、Ruby、Java™)都有模板引擎,而 PHP 也不例外。在搜索引擎中键入 PHP template engine,然后您可能会找到 25 个以上的选项(有关强调所研究的每个引擎功能的列表 The PHP Template Engine Roundup,请参阅 参考资料)。

一些 PHP 模板引擎进行了速度优化。其他 PHP 模板引擎旨在鼓励分离表单与函数的同时简化使用。在某些包中,占位符是在 PHP 本身中描述的,而其他解决方案都有一种自定义的简短编程语言。如何选择模板引擎在很大程度上取决于要求,因此适宜进行少量研究和试验。

在这里,我向您介绍 Smarty,它是最流行的 PHP 模板引擎之一。Smarty “代码” 有它自己的语法和运算符扩展列表,但是系统并不难学。阅读或浏览 Smarty 文档,以便熟悉它的所有功能。从 Smarty 的小修改开始,根据需求扩展您的技能,然后越来越精通。

获得 Smarty

Smarty Web 站点维护着一张活动邮件列表、一个支持论坛和一个 Internet Relay Chat (IRC) 论坛(请参阅 参考资料)。开发正在进行,而本文基于 V2.6.18 版本,该版本发布于 2007 年 3 月 7 日。

Smarty 有两个方面:PHP 应用程序编程接口 (API) 和显示引擎。应用程序代码将调用 API 把代码变量与模板占位符关联起来,而显示引擎将解释 Smarty 标记、执行循环、引用占位符和显示最终结果。Smarty 功能包括:

用于显示 PHP 的所有基本数据结构的运算符
显示简单变量,迭代整个数组或关联数组,以及显示类的成员。
占位符的默认值
如果 PHP 代码没有将变量与占位符关联,则显示默认值。
控制运算符,例如 ifthenelse,可以根据输入数据选择动态显示哪些内容
例如,设计人员可以选择用加粗的红色文本显示负账户余额,而用黑色文本显示正余额。您可以在模板中隔离此类显示逻辑(使您可以更轻松地进行开发)。
循环控制,它将提供用于简化构建列表和表的特殊变量
例如,可以测试循环的第一次迭代并创建表头。还可以像循环迭代一样循环执行值轮循 (round-robin) 列表,循环迭代非常适于改变表行的颜色。
渲染时用于改变数据的修饰符
例如,可以用 Smarty 标记 <strong>{$name|upper}</strong> 大写加粗显示占位符 —— 如 $name

<strong> 是普通 HTML。大括号 ({}) 用于划定 Smarty 标记,$name 是占位符,而 |upper 是修饰符。还可以编写自己的修饰符以扩展 Smarty 的功能。
如果必须 包括脚本和原始 PHP 代码,可以用 literal 和 php 运算符来完成
literal 运算符内的所有内容都将被逐字传递给最终页面。php 运算符中放置的代码将像嵌入到 <?php ... ?> 转义符内一样执行。

还可以通过 {include ...} 运算符重用 Smarty 模板。要提高性能,则需缓存每个模板,以避免每次使用的转换负载。Smarty Web 站点提供了丰富文档和示例。Packt Publishing 还提供一本名为Smarty: PHP Template Programming and Applications(请参阅 参考资料)的书,该书适于学习和参考(警告:一些最新运算符并未介绍,而且其他运算符的说明也不正确,因为该书介绍的是 Smarty V2.x 的早期版本)。





回页首


用 Smarty 进行开发

无法通过一篇文章列举和演示 Smarty 的所有功能。但是,即使是一个如下所示的小示例,也能证明模板的力量。

把 Smarty 添加到应用程序中十分轻松:

  1. 下载 Smarty.zip 演示代码(请参阅 下载)。
  2. 解压缩并把 Smarty 安装到路径中。
  3. 编写要求使用 Smarty 类的应用程序。
  4. 创建两个目录一起放置应用程序:
    • templates 将包含模板
    • templates_c 将包含缓存的模板

例如,示例应用程序的文件夹内容包含 Example.class.php index.php templates/ templates_c/

模板目录中的文件将由 Smarty 引擎读取。确保 Web 服务器对那些文件拥有适当的访问权。另外,templates_c 的内容必须可读可写,因为缓存的模板副本放置在该文件夹中。至少要使 Web 服务器可以将数据写入 templates_c。或者,如果不需要考虑安全问题,可以将目录更改为模式 777

清单 1 显示了 Example.class.php,这是一个有代表性的 PHP V5 类。清单 2 包含 index.php,即应用程序。图 1 中显示了用浏览器访问示例应用程序的结果。


清单 1. 简单 PHP V5 类,用于存储任意类型的已命名属性的随机列表
                
<?php

//
// Example is a simple class that stores an arbitrary 
// number of named properties. 
//

class Example {
    private $catalog = array();
    
    public function SetProperties( $arrayVariables ) {
        foreach ( $arrayVariables as $name => $value ) {
            $this->SetProperty( $name, $value );
        }
    }
    
    public function SetProperty( $name, $value ) {
        $this->$name = $value;
        $this->catalog[] = $name;
    }
    
    public function GetProperties( ) {
        $result = array();
        foreach ( $catalog as $name ) {
            $result[$name] = $this->GetProperty( $name );
        }
        
        return( $result );
    }
    
    public function GetProperty( $name ) {
        return ( $this->$name );
    }
}
?>

Example 是一个简单类,用于持久保存任意数目的已命名属性。该类最令人感兴趣的部分是第 18 行 $this->$name = $value;。这行代码将动态创建类实例成员。例如,如果调用 $example->SetProperty( 'name', 'Groucho' ),则可以用(传统的)$example->name 检索名称。


清单 2. PHP 应用程序,完全没有任何 Web 页面标记
                
<?php
require( 'Smarty.class.php' );
require( 'Example.class.php' );

$groucho = new Example();
$groucho->SetProperty( 'name', 'Groucho' );
$groucho->SetProperty( 'quote', 
    'Time flies like an arrow. Fruit flies like a banana.' 
);

$chico = new Example();
$chico->SetProperties( array(
        'name' => 'Chico',
        'quote' => "There's no such thing as a sanity clause!"
    )
);

$movies = new Example();
$movies->SetProperties( array(
    'movies' => array(
        'A Night at the Opera',
        'Horse Feathers',
        'Coconuts',
        'The Big Store'
    ))
);

$looks = new Example();
$looks->SetProperty( 'novelty', array(
        array( name =>'Groucho', 'signature' => 'moustache' ),
        array( name =>'Chico', 'signature' => 'hat' ),
        array( name => 'Harpo', 'signature' => 'raincoat' ),
        array( name => 'Zeppo', 'signature' => 'hair')
    )
);

$smarty = new Smarty();
$smarty->assign( 'person', $chico );
$smarty->assign( 'people', $looks->novelty );
$smarty->assign( 'quote', $groucho->quote );
$smarty->assign( 'movies', $movies->movies );
$smarty->display( 'template.tpl' );
?>

清单 2 反映了把 PHP 变量与 Smarty 占位符关联起来的一般策略。代码行 $smarty->assign( 'name', $x ) 将把 PHP 变量(或数组、对象)$x 与占位符名称关联起来。模板中显示 name 的所有位置都将显示 $x 的值。


图 1. 渲染最终页面,结合表单与函数
渲染最终页面,结合表单与函数 

Smarty 模板是什么样的?Smarty 代码都是轻量级的,如清单 3、清单 4 和清单 5 所示。Smarty 将把大括号 ({}) 中的所有内容都视为 Smarty 代码。因此,如果任何其他页面标记(例如嵌入式 CSS 或 JavaScript)使用大括号,则必须用 {literal}...{/literal} 把那个标记括起来,如清单 3 中所示:


清单 3. 主模板中包括的简单 header 模板
                
<html>
<head>
	<title>{$title|default:'The Marx Brothers'}</title>
	<style type="text/css">
	{literal}
	body {
	    font-family: Verdana, Arial, sans-serif;
	    margin: 5%;
	}
	{/literal}
	</style>
</head>
<body>

如前所述,清单 3 将应用 {literal} 运算符来逐字渲染标记:定界符之间的所有文本都将被传递而无需进一步解释。第 3 行将显示名为 <title> 的占位符的值,该占位符与 PHP 应用程序中的标量变量相关联。如果不与 <title> 关联,则 |default: 修饰符将提供默认值。注意 Smarty 运算符中的空白。通常,必须忽略它。幸运的是,Smarty 编译器将提供有帮助的错误消息。

清单 4 页脚显示了使用 {if condition} 在渲染时做出决定。在这里,如果占位符 quote 的值已设定,则将显示 {if} 与 {/if} 之间插入的标记。代码行 {$quote|upper} 将用全大写的形式发送 quote 的值。|upper 是改变字符串输出的众多修饰符之一 —— 同时,它对于分离字符串内容与显示形式十分有用。


清单 4. 页脚模板
                
<div style="clear: both;">
    <p align="center">
        {if $quote}
            <{$style|default:'strong'}>
                {$quote|upper}        
            </{$style|default:'strong'}>
        {/if}
    </p>
</div>
</body>
</html>

清单 5 渲染了最终页面。


清单 5. 应用程序的主要 Smarty 模板
                
{include file='header.tpl'}

<p>
    {$person->name} said, "{$person->quote}"
</p>

<ul>
    {section name=index loop=$movies}
    <li>
        {$movies[index]}
    </li>
    {/section}
</ul> 

<table>
{foreach item=person from=$people name=people}
    {if $smarty.foreach.people.first}
        <tr>
            <th>#</th>
            <th>Name</th>
            <th>Signature</th>
        </tr>
    {/if}
    <tr bgcolor="{cycle values="#eeeeee,#d0d0d0}">
        <td>{$smarty.foreach.people.iteration}</td>
        <td>{$person.name}</td>
        <td>{$person.signature}</td>
    </tr>
{foreachelse}
    <tr><td>Print this only if there's no data.</td></tr>
{/foreach}
</table>

{include file='footer.tpl'}

应用程序的这个主要 Smarty 模板采用了若干个 Smarty 运算符:

{include file='filename'}
像是 PHP 自己的 include() 方法一样运行,在适当的位置立即插入和解释 filename 的内容。虽然并未显示,但是可以将变量从一个模板传递给另一个模板,这样做鼓励重用。
{$person->GetProperty('name')}
假定 person 与名为 GetProperty() 的方法相关。您可以调用对象的方法和引用对象成员,像 {$person->quote} 所做的那样。
{section name=index loop=$placeholder}
在数组内迭代。loop 属性将给占位符命名,而 name 属性将指定一个名称以供数组索引使用。在循环内,将把数组元素作为 {$placeholder[index]} 来引用。
foreach
像 section 一样迭代,但是提供了一个非常优秀的功能来处理一组关联数组,例如数据库查询的行列表。每个关联数组都被 “转换” 到名为 item 的索引中。例如,在清单 5 中,person 被命名为item。每执行一次循环,person 就会被指定来自数组 people 的关联数组。在那之后,在整个循环过程中,可以通过关键字引用关联数组中的值,如 {$person.signature}
foreach 中的 name 属性
类似于 HTML 标记的 id 属性,它将惟一地识别循环。使用此 ID 来引用反映循环状态的特殊变量集。例如,一个特殊变量是 first,它只在循环的第一次迭代时才被设定。因此,值$smarty.foreach.people.first 将引用与名为 people (people) 的 foreach 循环 (foreach) 关联的特殊 Smarty 变量 (smarty)。正如您可能会想到的那样,还有 last 值和 iteration 值,它们从 1 开始,并随每次迭代增加(如果需要从零开始的计数器,请使用 index 而不要使用 iteration)。
cycle
用于构建表的优秀运算符。如果提供 values 列表,Smarty 将像循环迭代一样在所有值中循环。将循环添加到 bgcolor 中将改变每个表行的颜色可以使表更清晰。
{foreachelse}
如果要迭代的数组为空,则转而显示 {foreachelse}...{/foreachelse} 的内容。

既然您已经预览了模板,那么 清单 2 读起来可能很简单。跟平常一样,清单 2 将执行计算并把渲染页面的工作传递给 Smarty。代码行 $smarty->display('template.tpl') 将渲染模板。要捕捉 Smarty 的输出,请使用 $smarty->fetch('template.tpl')





回页首


使用 Smarty 更聪明一点,而不是更辛苦一点

虽然本例是经过设计的,但是它展示了 Smarty 的强大之处和灵活性以及使用它分离标记与代码是多么简单。Smarty 还有更多技巧。Smarty 可能实现您所需要的几乎所有功能。您可以将模板输出捕捉到 Smarty 占位符中。您可以过滤模板,无论是在编译前,还是在编译后,还可以在渲染输出被显示或获取之前先进行处理。而且 Smarty 允许您缓存模板。

向 PHP 代码中添加 $smarty->caching = 1; 即可获得上述特性。如果缓存被启用,则调用 display('template.tpl') 将像往常一样渲染模板并将在缓存中保存一份模板副本。下一次调用display('template.tpl') 将利用缓存的副本,而不再渲染模板。

您可以控制缓存的有效期、手动清空缓存,并且如果在保存缓存版本后模板文件发生更改,可以使缓存可以自动刷新。如果希望阅读类似 清单 2 的代码,请把 Smarty 应用到 Web 项目中。

分享到:
评论

相关推荐

    php之smarty入门

    - **明确分离**:遵循“将程序应用逻辑与网页呈现逻辑明确分离”的原则,确保PHP程序中的HTML代码最少。 - **模块化设计**:合理规划模版结构,以便于复用和维护。 #### 七、Smarty的安装与配置 1. **确定安装位置...

    PHP之Smarty入门

    **Smarty** 是一种基于PHP的模版引擎,它的主要目的是实现业务逻辑(即程序逻辑)与界面展示逻辑的分离。这种分离有助于提高代码的可维护性和可扩展性,使得开发者和前端设计师可以更加专注于各自的专业领域。 ####...

    smarty3中文手册

    Smarty3是一个强大的PHP模板引擎,它的设计目标是将HTML代码与PHP代码分离,使得开发者能够更专注于页面的布局和设计,而不用关心程序逻辑。这个"smarty3中文手册"是针对Smarty3框架的详细文档,提供了全面的指南、...

    smarty3 入门实例

    这意味着我们将探讨如何开始使用Smarty3来构建PHP应用程序。在PHP开发中,使用Smarty可以使得程序员编写业务逻辑,而设计师则专注于页面的布局和设计。Smarty3引入了新的特性,如对象导向的编程接口,增强了模板继承...

    2014年辛星PHP教程秋季版之Smarty模板.pdf )

    模板的目的是将程序的逻辑部分与表示部分分离,即将数据处理的方式与数据展示的形式分开。这是一个常见的误解,许多人认为模板是将PHP代码和HTML代码分开,但实际上模板是将后端处理数据的逻辑与前端展示数据的形式...

    smarty实例教程

    Smarty 变量:{$name},Smarty 中的核心组成,采用 Smarty 定义的左边界符 { 与右边界符 } 包含着,以 PHP 变量形式给出,在 Smarty 程序中将使用 `$smarty-&gt;assign("name", "李晓军") ;` 将模板中的 $name 替换成...

    php MVC开发模式及smarty模板介绍

    它将应用程序分为三个核心部分:**模型(Model)**、**视图(View)**和**控制器(Controller)**,每部分承担着特定的功能。 ##### 1.1 控制器(Controller) - **作用**:控制器是应用程序的指挥中心,负责接收...

    Smarty3~~~~~~~~

    在 Smarty3 中,API(应用程序编程接口)进行了重构,以提高其面向对象的结构和语法一致性。尽管 Smarty2 的 API 仍被支持,但使用时会给出提示,建议用户迁移到新的语法。例如,设置缓存目录的方法已从 `$smarty-&gt;...

    菜鸟学PHP之Smarty入门.rar

    因此也就有人想到,如果能把程序应用逻辑 (或称商业应用逻辑) 与网页呈现 (Layout) 逻辑分离的话,是不是会比较好呢?   其实这个问题早就存在已久,从交互式网页开始风行时,不论是 ASP 或是 PHP 的使用者都是身...

    基于PHP的留言本smarty版源码.zip

    它支持变量替换、循环、条件判断等复杂操作,为开发高效、整洁的Web应用程序提供了便利。 二、留言本功能分析 基于PHP的留言本系统通常包含以下核心功能: 1. **用户提交留言**:用户可以填写姓名、邮箱和留言...

    一款基于MVC模式并集成了Smarty3模板引擎的PHP框架

    PHP与MySQL的结合是Web开发中的经典组合,因为MySQL是一个高效、灵活的关系型数据库管理系统,能为PHP应用提供稳定的数据存储服务。它们共同构成了许多动态网站的基础,尤其在中小型企业级应用中非常常见。 “web...

    smarty:Smarty是PHP的模板引擎,有助于将表示形式(HTMLCSS)与应用程序逻辑分离

    阅读NEW_FEATURES和INHERITANCE_RELEASE_NOTES文件,以获取对Smarty 3.1功能的最新扩展 Smarty版本3.1.11或更高版本现在位于github上,可以与Composer一起安装。 “ smarty / smarty”包将从libs / ....子文件夹...

    smarty中文手册

    Smarty是一个流行的PHP模板引擎,它的主要目标是将呈现逻辑与应用程序的业务逻辑分离,从而实现MVC(模型-视图-控制器)设计模式。这个"Smarty中文手册"提供了全面的指导,帮助开发者理解和掌握Smarty的使用。 ...

    smarty入门

    Smarty是一个广泛使用的PHP模板引擎,它的主要目的是将呈现逻辑(视图)与应用程序逻辑分离,以实现更清晰的代码结构和更好的开发效率。本篇文章将深入讲解Smarty的基础知识,帮助初学者快速入门。 1. **Smarty简介...

    Smarty手册

    其核心特点是将模板与应用程序代码完全隔离,使得前端设计人员可以独立于后端开发者进行工作,无需了解PHP或其他编程语言。 **1.2 安装要求与步骤** - **要求:** Smarty要求服务器环境至少支持PHP 4.1.0或更高...

    PHP实例开发源码-问问程序php伪静态不完整版.zip

    5. **模板引擎**:为了实现前后端分离,很多PHP程序会使用模板引擎,如Smarty或Twig。即使这个程序没有使用模板引擎,我们也可以自己分析其HTML输出和PHP代码混合的方式,理解动态内容的生成过程。 6. **错误处理与...

    smarty简单应用实例

    Smarty是一种流行的PHP模板引擎,它允许设计师和...最后,文章强调了Smarty模板引擎在PHP程序设计中的实际应用价值,并鼓励读者参考这个简单的实例进行自学,以便能够运用Smarty模板引擎来改善自己Web项目的开发流程。

    PHP实例开发源码-php搜索链接程序 LinkMan.zip

    9. **模板引擎**:为了使代码和视图分离,LinkMan可能使用了模板引擎,如Smarty,将PHP逻辑与HTML展示部分分开,提高代码可维护性。 10. **面向对象编程**:现代PHP支持面向对象编程,LinkMan可能包含类定义、继承...

    ppi-smarty-module:适用于PPI2的Smarty3模板引擎模块

    聪明的 Smarty是PHP的模板引擎,有助于将表示形式(HTML / CSS)与应用程序逻辑分离。 这意味着PHP代码是应用程序逻辑,并且与表示分离。 Smarty的一些功能: 这是非常快的。 由于PHP解析器会执行肮脏的工作,因此...

    smarty内置函数foreach用法实例

    Smarty是PHP开发中使用的一个模板引擎,它通过将逻辑层和表现层分离,使得开发人员能够轻松地创建易于管理和维护的Web应用程序。...正确掌握并运用Smarty的foreach函数,对于创建高性能的PHP应用程序具有重要意义。

Global site tag (gtag.js) - Google Analytics