Smarty 模板引擎入门教程
目录
-
第一部分:什么是 Smarty?为什么要用它?
- 1 定义与核心思想
- 2 使用 Smarty 的好处
- 3 谁适合学习 Smarty?(以及现代替代方案)
-
第二部分:环境准备与安装
- 1 系统要求
- 2 安装 Smarty(Composer 方式,最推荐)
- 3 项目目录结构
-
第三部分:核心概念与基本使用
- 1 模板文件
- 2 PHP 脚本(分配变量)
- 3 模板引擎(初始化与渲染)
- 4 变量输出
- 5 注释
- 6 常用配置项
-
第四部分:Smarty 常用功能详解
- 1 修饰器 - 格式化变量
- 2 内建函数 - 流程控制
{if}...{/if}条件判断{foreach}...{/foreach}数组循环{section}...{/section}数字循环(较少用)
- 3 包含文件与继承
{include}包含子模板{extends}与{block}模板继承(高级功能)
-
第五部分:一个完整的实战案例
- 1 需求分析
- 2 项目结构
- 3 编写 PHP 脚本
- 4 编写模板文件
- 5 运行效果
-
第六部分:总结与展望
第一部分:什么是 Smarty?为什么要用它?
1 定义与核心思想
Smarty 是一个用 PHP 编写的模板引擎,它的核心思想是 “关注点分离”(Separation of Concerns)。
就是把 PHP 代码(业务逻辑) 和 HTML 代码(页面展示) 分离开。
- PHP 文件:负责处理数据、数据库查询、业务计算等“后台”工作。
- 模板文件:负责展示数据、设计页面布局等“前台”工作,它看起来很像 HTML,但里面可以嵌入 Smarty 的特定标签。
2 使用 Smarty 的好处
- 代码清晰,易于维护:前端开发者可以专注于 HTML/CSS/JS,而不用担心 PHP 代码的复杂性,后端开发者则专注于业务逻辑,无需关心页面样式,修改页面布局时,只需修改
.tpl文件,而不会触碰核心的 PHP 业务代码。 - 提升安全性:Smarty 默认会对所有输出到模板的变量进行 HTML 转义,可以有效防止 XSS 跨站脚本攻击,虽然可以关闭此功能,但默认开启是一个非常好的安全实践。
- 提高开发效率:模板引擎提供了很多便捷的语法(如循环、条件判断),让复杂的页面逻辑在模板中就能实现,减少了在 PHP 中拼接 HTML 字符串的繁琐工作。
- 可重用性:通过
{include}和模板继承,可以轻松创建公共的头部、底部、导航栏等,并在多个页面中复用。
3 谁适合学习 Smarty?(以及现代替代方案)
适合场景:
- 学习模板引擎的基本概念和工作原理。
- 维护一些使用 Smarty 构建的旧项目。
- 在某些小型项目中,希望快速实现前后端分离。
现代替代方案: 在现代 PHP 开发中,随着 MVC 框架(如 Laravel, Symfony)的普及,人们更倾向于在控制器中直接传递数据给 Blade、Twig 等现代模板引擎,它们通常与框架深度集成,功能更强大,语法也更简洁。
Twig(Symfony 框架使用)是目前最流行的 PHP 模板引擎之一,其语法非常优雅,功能强大,但从学习角度看,Smarty 的概念与 Twig 高度相似,学懂了 Smarty,再学 Twig 会非常容易。
第二部分:环境准备与安装
1 系统要求
- PHP 5.2+ (推荐 7.0+)
- 一个 Web 服务器(如 Apache 或 Nginx)
- Composer(PHP 依赖管理工具,强烈推荐)
2 安装 Smarty(Composer 方式,最推荐)
-
安装 Composer:如果你的系统还没有 Composer,请先从 getcomposer.org 下载并安装。
-
创建项目目录:
mkdir smarty_project cd smarty_project
-
使用 Composer 安装 Smarty: 在项目根目录下执行命令:
composer require smarty/smarty
执行后,你的项目目录下会出现一个
vendor文件夹,里面包含了 Smarty 的所有源码。
3 项目目录结构
一个规范的 Smarty 项目目录结构如下:
smarty_project/
├── vendor/ // Composer 自动生成的依赖包
│ └── smarty/
├── app/ // 应用程序目录
│ ├── controllers/ // 控制器目录 (可选)
│ └── templates_c/ // Smarty 编译后的模板缓存目录 (重要!)
├── templates/ // 模板文件目录
│ ├── layouts/ // 布局模板
│ │ └── main.tpl
│ └── index.tpl // 首页模板
├── index.php // 入口文件
└── composer.json // Composer 配置文件
注意:
templates_c目录必须存在,Web 服务器(如 Apache/Nginx 的运行用户)需要有写入权限,Smarty 会把模板文件编译成 PHP 代码存放在这里以提高性能。templates目录存放我们写的.tpl文件。
第三部分:核心概念与基本使用
1 模板文件
模板文件是纯文本文件,通常以 .tpl 为后缀,它包含 HTML 和 Smarty 标签。
示例 templates/index.tpl:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">我的第一个 Smarty 页面</title>
</head>
<body>
<h1>欢迎来到 {$pageTitle}</h1>
<p>今天是 {$currentDate}。</p>
</body>
</html>
{$pageTitle} 和 {$currentDate} Smarty 的变量标签,里面的值将由 PHP 脚本传入。
2 PHP 脚本(分配变量)
PHP 脚本负责创建数据,并将其“分配”给 Smarty。
示例 index.php:
<?php
// 1. 引入 Composer 的自动加载文件
require 'vendor/autoload.php';
// 2. 创建 Smarty 对象
$smarty = new Smarty();
// 3. 配置 Smarty 的目录路径
$smarty->setTemplateDir(__DIR__ . '/templates'); // 设置模板目录
$smarty->setCompileDir(__DIR__ . '/app/templates_c'); // 设置编译目录
$smarty->setCacheDir(__DIR__ . '/app/cache'); // 设置缓存目录 (可选)
// 4. 分配变量
$smarty->assign('pageTitle', 'Smarty 学习教程');
$smarty->assign('currentDate', date('Y-m-d H:i:s'));
// 5. 显示模板
$smarty->display('index.tpl');
?>
3 模板引擎(初始化与渲染)
上面的 PHP 脚本完成了三件事:
- 引入:通过
composer的自动加载器加载 Smarty 类。 - 配置:告诉 Smarty 模板文件和编译文件分别放在哪里。
- 执行:
assign():将 PHP 变量名和值传递给 Smarty。display():加载指定的模板文件,用分配的变量替换模板中的标签,然后将最终生成的 HTML 输出到浏览器。
4 变量输出
-
简单变量:
{$variableName}{$pageTitle}会输出 "Smarty 学习教程"。
-
数组变量:
// PHP 中 $user = ['name' => '张三', 'age' => 30]; $smarty->assign('user', $user); // 模板中 姓名: {$user.name} 或 {$user['name']} <br> 年龄: {$user.age} -
对象属性:
// PHP 中 class User { public $name = '李四'; } $smarty->assign('user_obj', new User()); // 模板中 姓名: {$user_obj->name}
5 注释
Smarty 注释不会在最终的 HTML 源码中显示,非常安全。
{* 这是一个Smarty注释,前端用户看不到 *}
6 常用配置项
可以在创建 Smarty 对象后进行配置:
$smarty = new Smarty(); // 关闭缓存(开发时建议开启,方便调试) $smarty->caching = false; // 模板文件后缀 $smarty->template_ext = 'tpl'; // 是否检查模板文件是否被修改(开发时建议开启) $smarty->compile_check = true;
第四部分:Smarty 常用功能详解
1 修饰器 - 格式化变量
修饰器用于格式化变量的输出,用 符号连接。
{$price|default:'0.00'} {* $price 未设置,则显示 '0.00' *}
{$longText|truncate:50} {* 截断长文本,只显示前50个字符 *}
{$name|upper} {* 将 $name 转换为大写 *}
{$date|date_format:'%Y-%m-%d'} {* 格式化日期 *}
2 内建函数 - 流程控制
{if}...{/if} 条件判断
{if $user.age >= 18}
<p>{$user.name} 已成年。</p>
{elseif $user.age > 0}
<p>{$user.name} 是未成年。</p>
{else}
<p>年龄信息未知。</p>
{/if}
{foreach}...{/foreach} 数组循环
这是最常用的循环方式。
<ul>
{foreach $products as $product}
<li>
<strong>{$product.name}</strong> - 价格: {$product.price} 元
</li>
{/foreach}
</ul>
获取循环信息:
{$product} 是当前元素,你还可以使用 {$@key} 和 {$@iteration} 来获取键和迭代次数。
{foreach $products as $key => $product}
{if $@iteration is even}
<li style="background-color: #f0f0f0;"> {* 偶数行高亮 *}
{else}
<li>
{/if}
ID: {$@key}, 名称: {$product.name}, 序号: {$@iteration}
</li>
{/foreach}
{section}...{/section} 数字循环
这个函数用于循环一个固定范围的数字,现在较少使用,但了解一下也无妨。
{section name=i loop=5}
<p>这是第 {$i.index + 1} 次循环。</p>
{/section}
3 包含文件与继承
{include} 包含子模板
用于将一个模板文件嵌入到另一个模板文件中,非常适合创建公共的头部、底部等。
templates/header.tpl:
<head>{$pageTitle|default:'默认标题'}</title>
</head>
<body>
<header>网站头部导航</header>
templates/footer.tpl:
<footer>网站底部信息 © 2025</footer> </body> </html>
templates/index.tpl:
{include file='header.tpl'}
<main>
<h1>主页内容</h1>
<p>这里是主页的主体内容。</p>
</main>
{include file='footer.tpl'}
{extends} 与 {block} 模板继承(高级功能)
这是更强大的复用机制,类似于面向对象中的继承。
-
创建一个父模板(布局模板)
templates/layouts/main.tpl:<!DOCTYPE html> <html> <head> <title>{block name='title'}默认网站标题{/block}</title> <link rel="stylesheet" href="style.css"> </head> <body> <header>网站头部</header> {block name='content'} <!-- 这是默认内容,如果子模板不覆盖,就会显示这个 --> <p>这是默认的页面内容。</p> {/block} <footer>网站底部</footer> </body> </html> -
创建一个子模板,继承父模板
templates/index.tpl:{extends 'layouts/main.tpl'} {block name='title'} 首页 - 我的网站 {/block} {block name='content'} <h1>欢迎来到首页!</h1> <p>这是首页特有的内容,它覆盖了父模板中的默认内容。</p> {/block}子模板通过
{extends}指定父模板,然后通过{block}覆盖父模板中同名的块,这种方式让布局管理变得非常清晰和高效。
第五部分:一个完整的实战案例
1 需求分析
创建一个简单的文章列表页面,页面包含:
- 一个公共的头部和底部。
- 一个文章列表,每篇文章显示标题、作者和发布日期。
- 使用模板继承来布局。
2 项目结构
沿用第二部分的目录结构。
smarty_project/
├── vendor/
├── app/
│ └── templates_c/
├── templates/
│ ├── layouts/
│ │ └── main.tpl
│ └── article_list.tpl
├── index.php
└── composer.json
3 编写 PHP 脚本 (index.php)
<?php
require 'vendor/autoload.php';
$smarty = new Smarty();
$smarty->setTemplateDir(__DIR__ . '/templates');
$smarty->setCompileDir(__DIR__ . '/app/templates_c');
// 1. 模拟从数据库获取文章数据
$articles = [
[
'id' => 1,
'title' => 'Smarty 模板引擎入门指南',
'author' => '张三',
'date' => '2025-10-25'
],
[
'id' => 2,
'title' => 'PHP 面向对象编程详解',
'author' => '李四',
'date' => '2025-10-24'
],
[
'id' => 3,
'title' => '使用 Composer 管理项目依赖',
'author' => '王五',
'date' => '2025-10-23'
]
];
// 2. 分配变量给模板
$smarty->assign('pageTitle', '文章列表');
$smarty->assign('articles', $articles);
// 3. 显示模板
$smarty->display('article_list.tpl');
?>
4 编写模板文件
父模板 templates/layouts/main.tpl:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">{block name='page_title'}默认标题{/block}</title>
<style>
body { font-family: sans-serif; }
header, footer { background: #333; color: white; text-align: center; padding: 10px; }
article { border: 1px solid #ccc; margin: 10px; padding: 15px; border-radius: 5px; }
</style>
</head>
<body>
<header>我的博客网站</header>
<main>
{block name='content'}{/block}
</main>
<footer>© 2025 All Rights Reserved.</footer>
</body>
</html>
子模板 templates/article_list.tpl:
{extends 'layouts/main.tpl'}
{* 覆盖父模板的标题块 *}
{block name='page_title'}
{$pageTitle}
{/block}
{* 覆盖父模板的内容块 *}
{block name='content'}
<h1>所有文章</h1>
{foreach $articles as $article}
<article>
<h2><a href="article.php?id={$article.id}">{$article.title}</a></h2>
<p>
<small>作者: {$article.author} | 发布日期: {$article.date}</small>
</p>
</article>
{/foreach}
{/block}
5 运行效果
将项目部署到你的 Web 服务器(如 Apache 的 htdocs 或 Nginx 的 html 目录),然后访问 index.php,你将看到一个样式良好的文章列表页面。
第六部分:总结与展望
恭喜!你已经完成了 Smarty 的入门学习,现在你应该掌握了:
- Smarty 的核心思想和优势。
- 如何安装和配置一个 Smarty 项目。
- 如何在 PHP 和模板之间传递变量。
- 如何使用 Smarty 的基本语法:变量、注释、修饰器。
- 如何使用
{if},{foreach}进行逻辑控制。 - 如何使用
{include}和{extends}实现模板的复用和继承。
下一步可以学习的内容:
- 缓存:Smarty 有强大的缓存功能,可以极大提高网站性能,学习如何开启和使用缓存。
- 插件:你可以编写自己的修饰器或函数来扩展 Smarty 的功能。
- 配置文件:学习如何使用外部配置文件来管理网站的全局变量。
虽然现代框架更多地使用 Twig 等新一代模板引擎,但 Smarty 所代表的 “模板与逻辑分离” 的思想是整个 Web 开发领域的重要基石,掌握它,不仅能让你轻松维护旧项目,更能让你深刻理解现代前端框架(如 Vue, React)中组件化思想的根源。
