Smarty 教程:从入门到精通
目录
- 什么是 Smarty?
- 为什么使用 Smarty?(优点与缺点)
- 环境准备与安装
- Smarty 基础入门
- 第一个 "Hello, World" 程序
- 变量输出
- 注释
- 核心功能详解
- 变量
- 从 PHP 传递变量
- 配置文件变量
- 系统变量 (
$smarty,$smarty.now等)
- 修饰器
- 函数
- 内建函数 (
{if},{foreach},{include},{capture}等) - 自定义函数
- 内建函数 (
- 配置文件
- 变量
- 高级特性
- 缓存
- 自定义插件
- 最佳实践与项目结构
什么是 Smarty?
Smarty 是一个用 PHP 编写的模板引擎,它的核心思想是关注点分离,即将应用程序逻辑与表现逻辑分离开。

- PHP 文件 (后端逻辑):负责处理数据库、业务逻辑、计算等,它准备好需要显示的数据。
- 模板文件 (前端表现):负责如何展示数据,它只关心 HTML、CSS 和如何格式化数据,不包含任何 PHP 代码。
PHP 代码将数据“分配”给模板,Smarty 引擎将模板编译成 PHP 文件并执行,最终生成用户看到的 HTML 页面。
一个简单的比喻:
- PHP 是一个厨师,负责准备食材(数据)。
- 模板 是一份菜谱,规定了如何摆盘和装饰(HTML 结构)。
- Smarty 是一个帮厨,根据菜谱(模板)和食材(数据)做出最终的菜肴(HTML 页面)。
为什么使用 Smarty?(优点与缺点)
优点
- 关注点分离:这是最大的优点,前端开发者可以专注于 HTML/CSS/JS,而不需要理解 PHP 逻辑;后端开发者则专注于业务逻辑,无需关心页面布局。
- 提高开发效率:设计师和程序员可以并行工作,互不干扰。
- 模板语法简单:对于前端人员来说,
{$variable}和{if $condition}比<?php echo $variable; ?>和<?php if ($condition) { ?>更直观、更安全。 - 安全性:默认情况下,Smarty 会转义 HTML 标签,可以有效防止 XSS(跨站脚本)攻击。
- 缓存机制:Smarty 内置强大的缓存功能,可以显著提高网站性能,减轻服务器负担。
- 可读性和可维护性:代码结构清晰,模板文件干净整洁,易于维护和修改。
缺点
- 增加了一层抽象:对于非常简单的页面,使用 Smarty 可能显得有些“杀鸡用牛刀”,会增加一点点性能开销(虽然现代版本已非常优化)。
- 学习曲线:对于新手来说,需要额外学习 Smarty 的语法和概念。
- 调试可能更复杂:错误可能发生在 PHP 代码中,也可能发生在模板编译或渲染过程中。
环境准备与安装
前提: 你的服务器已安装 PHP。
安装方式:

最推荐的方式是使用 Composer 来管理 Smarty。
-
安装 Composer (如果尚未安装):
- 访问 getcomposer.org 下载并安装。
-
通过 Composer 安装 Smarty:
- 在你的项目根目录下,运行以下命令:
composer require smarty/smarty
- 在你的项目根目录下,运行以下命令:
-
项目结构: 一个典型的 Smarty 项目结构如下:
(图片来源网络,侵删)my_project/ ├── vendor/ # Composer 自动生成的依赖目录 │ └── smarty/ ├── src/ # 你的 PHP 源代码 │ └── index.php ├── templates/ # 存放你的模板文件 │ └── index.tpl ├── templates_c/ # Smarty 编译生成的 PHP 文件目录 (需要可写权限) ├── cache/ # Smarty 缓存文件目录 (需要可写权限) ├── configs/ # 存放配置文件 └── ... # 其他项目文件 -
设置目录权限:
templates_c和cache目录必须对 Web 服务器(如 Apache、Nginx)有写入权限。- 在 Linux/macOS 下,可以执行:
chmod 777 templates_c cache
注意:
777权限不安全,生产环境中应设置更严格的权限(如755),并确保 Web 服务器用户有写入权限。
Smarty 基础入门
第一个 "Hello, World" 程序
步骤 1:创建 PHP 文件 (src/index.php)
<?php
// 引入 Composer 的自动加载器
require 'vendor/autoload.php';
// 引入 Smarty 类
use Smarty;
// 创建 Smarty 对象
$smarty = new Smarty();
// 1. 设置模板目录
$smarty->setTemplateDir(__DIR__ . '/../templates');
// 2. 设置编译目录
$smarty->setCompileDir(__DIR__ . '/../templates_c');
// 3. 设置缓存目录
$smarty->setCacheDir(__DIR__ . '/../cache');
// 4. 设置配置目录 (可选)
$smarty->setConfigDir(__DIR__ . '/../configs');
// 将数据分配给模板
$smarty->assign('name', 'World');
// 显示模板
$smarty->display('index.tpl');
步骤 2:创建模板文件 (templates/index.tpl)
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">Smarty 教程</title>
</head>
<body>
<h1>Hello, {$name}!</h1>
</body>
</html>
步骤 3:运行
访问 http://localhost/my_project/src/index.php,你应该能看到 "Hello, World!"。
变量输出
- 简单变量:
{$variable_name} - 数组:
- 索引数组:
{$my_array[0]} - 关联数组:
{$my_array.key}
- 索引数组:
- 对象属性:
{$my_object->property}
PHP 代码示例:
$smarty->assign('user', [
'name' => '张三',
'age' => 30,
'skills' => ['PHP', 'JavaScript', 'Smarty']
]);
$smarty->assign('title', '用户信息');
模板代码示例 (user_profile.tpl):
<h1>{$title}</h1>
<p>姓名: {$user.name}</p>
<p>年龄: {$user.age}</p>
<p>技能:</p>
<ul>
{foreach $user.skills as $skill}
<li>{$skill}</li>
{/foreach}
</ul>
注释
Smarty 模板中的注释不会出现在最终的 HTML 源码中。
{* 这是一个 Smarty 注释,用户在浏览器中是看不到的 *}
<!-- 这是一个 HTML 注释,用户可以在浏览器源码中看到 -->
核心功能详解
变量
- 从 PHP 传递变量:使用
$smarty->assign('var_name', $value)和$smarty->assignByRef('var_name', &$reference_value)。 - 配置文件变量:在
configs目录下创建.conf文件,然后在模板中通过{#variable_name#}使用。 - 系统变量:
{$smarty.now}:当前时间戳。{$smarty.const.SOME_CONSTANT}:访问 PHP 常量。{$smarty.template}:当前模板文件名。{$smarty.version}:Smarty 版本号。
修饰器
修饰器用于修改变量的输出,使用 符号,可以链式调用。
{$variable|modifier1|modifier2}
常用修饰器:
capitalize: 首字母大写。count_characters: 计算字符数。date_format: 格式化日期。{$smarty.now|date_format:"%Y-%m-%d %H:%M:%S"}default: 如果变量为空,使用默认值。{$name|default:"访客"}escape: 转义 HTML, URL 等。{$content|escape}(强烈建议在输出用户内容时使用)lower: 转为小写。upper: 转为大写。truncate: 截断字符串。{$long_text|truncate:50:"..."}
示例:
<p>格式化后: {$article.title|truncate:20|upper}</p>
函数
内建函数
-
{if}...{elseif}...{else}...{/if}{if $user.age >= 18} <p>您已成年。</p> {elseif $user.age > 0} <p>您是未成年人。</p> {else} <p>年龄未知。</p> {/if} -
{foreach}...{/foreach}和{section}...{/section}{foreach}是推荐使用的,功能更强大。<ul> {foreach $products as $product} <li>{$product.name} - ¥{$product.price}</li> {/foreach} </ul> {foreach $products key=$key item=$product} <p>索引: {$key}, 名称: {$product.name}</p> {/foreach} -
{include}包含其他模板文件,实现复用。{include file="header.tpl"} <main> <!-- 页面主要内容 --> </main> {include file="footer.tpl"} -
{capture}...{/capture}捕获模板块中的内容到一个变量中。{capture name='page_header'} <h1>欢迎来到我的网站</h1> <p>这里是副标题</p> {/capture} <!-- 在页面的其他地方使用这个变量 --> <header> {$smarty.capture.page_header} </header>
自定义函数
你可以创建自己的 PHP 函数并在模板中使用。
步骤 1:创建插件文件
在 plugins 目录下创建文件(如果没有则创建)。function.myFunction.php。
<?php
// function.myFunction.php
function smarty_function_myFunction($params, &$smarty) {
// $params 是一个包含模板中传递的参数的数组
$name = isset($params['name']) ? $params['name'] : '陌生人';
$repeat = isset($params['repeat']) ? (int)$params['repeat'] : 1;
$output = "<p>你好, {$name}!</p>";
// 返回的 HTML 会被插入到模板中
return str_repeat($output, $repeat);
}
步骤 2:在模板中使用
{myFunction name="Smarty 用户" repeat=3}
输出:
<p>你好, Smarty 用户!</p> <p>你好, Smarty 用户!</p> <p>你好, Smarty 用户!</p>
配置文件
-
在
configs目录下创建一个配置文件,site.conf:# site.conf site_name = "我的 Smarty 网站" site_author = "张三" meta_keywords = "smarty, php, 模板引擎" -
在模板中加载并使用配置变量:
{config_load file='site.conf'} <head> <title>{#site_name#}</title> <meta name="author" content="{#site_author#}"> <meta name="keywords" content="{#meta_keywords#}"> </head>
高级特性
缓存
Smarty 的缓存可以大幅提升性能,它将渲染好的 HTML 直接保存为静态文件。
基本用法:
-
开启缓存: 在 PHP 初始化 Smarty 时设置缓存时间。
$smarty = new Smarty(); // ... 其他设置 ... $smarty->caching = Smarty::CACHING_LIFETIME_CURRENT; // 开启缓存 $smarty->cache_lifetime = 3600; // 缓存存活 1 小时 (3600 秒)
-
检查和生成缓存:
// 检查缓存是否存在且有效 if (!$smarty->isCached('index.tpl')) { // 如果缓存不存在或已过期,则执行这些代码 // 这些代码中的 assign 只会在缓存生成时执行一次 $smarty->assign('time', date('Y-m-d H:i:s')); } // 显示模板 (如果缓存有效,则直接输出缓存) $smarty->display('index.tpl'); -
清除缓存:
// 清除单个模板的缓存 $smarty->clearCache('index.tpl'); // 清除所有缓存 $smarty->clearAllCache();
最佳实践与项目结构
一个健壮的项目结构至关重要。
my_project/
├── assets/ # 静态资源 (CSS, JS, images)
│ ├── css/
│ ├── js/
│ └── img/
├── src/ # PHP 源代码
│ ├── controllers/ # 控制器 (MVC 模式)
│ ├── models/ # 模型 (MVC 模式)
│ └── index.php # 入口文件
├── templates/ # 模板文件
│ ├── layouts/ # 布局模板 (如 header.tpl, footer.tpl)
│ │ ├── base.tpl # 基础布局
│ │ └── default.tpl # 默认布局
│ ├── pages/ # 页面特定模板
│ │ ├── index.tpl
│ │ └── about.tpl
│ └── partials/ # 可复用组件 (如 nav.tpl, article_card.tpl)
├── templates_c/ # 编译目录 (权限: 755)
├── cache/ # 缓存目录 (权限: 755)
├── configs/ # 配置文件
│ └── app.conf
└── vendor/ # Composer 依赖
最佳实践:
-
使用布局:创建一个
base.tpl作为所有页面的基础。{* templates/layouts/base.tpl *} <!DOCTYPE html> <html> <head> <title>{#site_name#} - {block name="title"}默认标题{/block}</title> {block name="head"}{/block} </head> <body> {include file="partials/header.tpl"} <main> {block name="content"}这里是默认内容{/block} </main> {include file="partials/footer.tpl"} </body> </html>然后在具体页面中继承它:
{* templates/pages/index.tpl *} {extends file="layouts/base.tpl"} {block name="title"}首页{/block} {block name="content"} <h1>欢迎来到首页!</h1> <p>当前时间: {$smarty.now|date_format:"%Y-%m-%d %H:%M:%S"}</p> {/block} -
复用组件:将导航栏、卡片等常用部分写成
partials,通过{include}引用。 -
合理使用缓存:对不常变化的内容(如页头、页脚、侧边栏)进行缓存。
-
保持模板简洁:模板中只应该有 HTML、Smarty 语法和简单的逻辑判断,复杂的业务逻辑一定要放在 PHP 中。
Smarty 是一个成熟、强大且功能丰富的模板引擎,虽然现代 PHP 框架(如 Laravel、Symfony)内置了更简洁的模板引擎(如 Blade、Twig),但 Smarty 的核心理念——关注点分离——在所有 Web 开发中都至关重要。
学习 Smarty 不仅是为了使用它,更是为了理解如何构建一个清晰、可维护、可扩展的 Web 应用程序,即使你未来使用其他框架,Smarty 的思想和模式也会对你大有裨益。
希望这份教程能帮助你顺利入门 Smarty!
