Smarty 教程:从入门到精通

目录

  1. 什么是 Smarty?
  2. 为什么使用 Smarty?(优点与缺点)
  3. 环境准备与安装
  4. Smarty 基础入门
    • 第一个 "Hello, World" 程序
    • 变量输出
    • 注释
  5. 核心功能详解
    • 变量
      • 从 PHP 传递变量
      • 配置文件变量
      • 系统变量 ($smarty, $smarty.now 等)
    • 修饰器
    • 函数
      • 内建函数 ({if}, {foreach}, {include}, {capture} 等)
      • 自定义函数
    • 配置文件
  6. 高级特性
    • 缓存
    • 自定义插件
  7. 最佳实践与项目结构

什么是 Smarty?

Smarty 是一个用 PHP 编写的模板引擎,它的核心思想是关注点分离,即将应用程序逻辑表现逻辑分离开。

smarty 教程
(图片来源网络,侵删)
  • PHP 文件 (后端逻辑):负责处理数据库、业务逻辑、计算等,它准备好需要显示的数据。
  • 模板文件 (前端表现):负责如何展示数据,它只关心 HTML、CSS 和如何格式化数据,不包含任何 PHP 代码。

PHP 代码将数据“分配”给模板,Smarty 引擎将模板编译成 PHP 文件并执行,最终生成用户看到的 HTML 页面。

一个简单的比喻:

  • PHP 是一个厨师,负责准备食材(数据)。
  • 模板 是一份菜谱,规定了如何摆盘和装饰(HTML 结构)。
  • Smarty 是一个帮厨,根据菜谱(模板)和食材(数据)做出最终的菜肴(HTML 页面)。

为什么使用 Smarty?(优点与缺点)

优点

  1. 关注点分离:这是最大的优点,前端开发者可以专注于 HTML/CSS/JS,而不需要理解 PHP 逻辑;后端开发者则专注于业务逻辑,无需关心页面布局。
  2. 提高开发效率:设计师和程序员可以并行工作,互不干扰。
  3. 模板语法简单:对于前端人员来说,{$variable}{if $condition}<?php echo $variable; ?><?php if ($condition) { ?> 更直观、更安全。
  4. 安全性:默认情况下,Smarty 会转义 HTML 标签,可以有效防止 XSS(跨站脚本)攻击。
  5. 缓存机制:Smarty 内置强大的缓存功能,可以显著提高网站性能,减轻服务器负担。
  6. 可读性和可维护性:代码结构清晰,模板文件干净整洁,易于维护和修改。

缺点

  1. 增加了一层抽象:对于非常简单的页面,使用 Smarty 可能显得有些“杀鸡用牛刀”,会增加一点点性能开销(虽然现代版本已非常优化)。
  2. 学习曲线:对于新手来说,需要额外学习 Smarty 的语法和概念。
  3. 调试可能更复杂:错误可能发生在 PHP 代码中,也可能发生在模板编译或渲染过程中。

环境准备与安装

前提: 你的服务器已安装 PHP。

安装方式:

smarty 教程
(图片来源网络,侵删)

最推荐的方式是使用 Composer 来管理 Smarty。

  1. 安装 Composer (如果尚未安装):

  2. 通过 Composer 安装 Smarty

    • 在你的项目根目录下,运行以下命令:
      composer require smarty/smarty
  3. 项目结构: 一个典型的 Smarty 项目结构如下:

    smarty 教程
    (图片来源网络,侵删)
    my_project/
    ├── vendor/                 # Composer 自动生成的依赖目录
    │   └── smarty/
    ├── src/                   # 你的 PHP 源代码
    │   └── index.php
    ├── templates/             # 存放你的模板文件
    │   └── index.tpl
    ├── templates_c/           # Smarty 编译生成的 PHP 文件目录 (需要可写权限)
    ├── cache/                # Smarty 缓存文件目录 (需要可写权限)
    ├── configs/              # 存放配置文件
    └── ...                   # 其他项目文件
  4. 设置目录权限

    • templates_ccache 目录必须对 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>

配置文件

  1. configs 目录下创建一个配置文件,site.conf

    # site.conf
    site_name = "我的 Smarty 网站"
    site_author = "张三"
    meta_keywords = "smarty, php, 模板引擎"
  2. 在模板中加载并使用配置变量:

    {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 直接保存为静态文件。

基本用法:

  1. 开启缓存: 在 PHP 初始化 Smarty 时设置缓存时间。

    $smarty = new Smarty();
    // ... 其他设置 ...
    $smarty->caching = Smarty::CACHING_LIFETIME_CURRENT; // 开启缓存
    $smarty->cache_lifetime = 3600; // 缓存存活 1 小时 (3600 秒)
  2. 检查和生成缓存

    // 检查缓存是否存在且有效
    if (!$smarty->isCached('index.tpl')) {
        // 如果缓存不存在或已过期,则执行这些代码
        // 这些代码中的 assign 只会在缓存生成时执行一次
        $smarty->assign('time', date('Y-m-d H:i:s'));
    }
    // 显示模板 (如果缓存有效,则直接输出缓存)
    $smarty->display('index.tpl');
  3. 清除缓存

    // 清除单个模板的缓存
    $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!