Smarty 是 PHP 經典的模板引擎,透過「編譯模板為 PHP 代碼」實現高效能,嚴格分離「邏輯 (PHP)」與「顯示 (Template)」。本文從安裝、目錄結構、基礎語法到實戰範例,完整引導快速上手。
composer require smarty/smarty
官網:https://www.smarty.net/ 下載最新穩定版,解壓至專案 `lib/Smarty/`
project/
├── lib/
│ └── Smarty/ # Smarty 核心庫
├── templates/ # 模板檔 (*.tpl)
├── templates_c/ # 編譯快取 (需寫入權限 775)
├── cache/ # 快取檔 (需寫入權限 775)
├── configs/ # 設定檔 (可選)
└── public/
└── index.php # 入口檔
<?php
require_once __DIR__ . '/lib/Smarty/libs/Smarty.class.php';
$smarty = new Smarty();
// 目錄設定 (絕對路徑最安全)
$smarty->setTemplateDir(__DIR__ . '/templates/');
$smarty->setCompileDir(__DIR__ . '/templates_c/');
$smarty->setCacheDir(__DIR__ . '/cache/');
$smarty->setConfigDir(__DIR__ . '/configs/');
// 開發環境關閉快取,正式環境開啟
$smarty->caching = false; // true = 開啟快取
$smarty->cache_lifetime = 3600; // 快取壽命 (秒)
// 定界符 (避免與 JS/Vue/React 語法衝突)
$smarty->left_delimiter = '<{';
$smarty->right_delimiter = '}>';
// 除錯模式
$smarty->debugging = false;
$smarty->error_reporting = E_ALL & ~E_NOTICE;
// 常用全域變數
$smarty->assign('SITE_NAME', 'My Website');
$smarty->assign('BASE_URL', 'https://example.com/');
<!-- 模板檔:templates/index.tpl -->
<html>
<head><title><{$page_title}></title></head>
<body>
<h1>歡迎 <{$user.name|default:'訪客'}> </h1>
<p>Email: <{$user.email|escape}></p>
<p>註冊時間: <{$user.created_at|date_format:'%Y-%m-%d'}></p>
</body>
</html>
| 修飾詞 | 功能 | 範例 |
|---|---|---|
| escape | HTML 編碼防 XSS | `{$var|escape}` / `{$var|escape:'htmlall'}` |
| default | 預設值 | `{$var|default:'無'}` |
| date_format | 日期格式化 | `{$time|date_format:'%Y-%m-%d %H:%M'}` |
| truncate | 截斷字串 | `{$long_text|truncate:50:'...'}` |
| strip_tags | 移除 HTML 標籤 | `{$html|strip_tags}` |
| upper/lower | 大小寫轉換 | `{$name|upper}` |
| replace | 字串替換 | `{$text|replace:'old':'new'}` |
| nl2br | 換行轉 <br> | `{$text|nl2br}` |
| count | 陣列長度 | `{$items|@count}` |
<{if $user.logged_in}>
<p>歡迎回來,<{$user.name}></p>
<{if $user.role == 'admin'}>
<a href="/admin">管理後台</a>
<{/if}>
<{elseif $user.banned}>
<p style="color:red">帳號已停用</p>
<{else}>
<a href="/login">請登入</a>
<{/if}>
<ul>
<{foreach $products as $product}>
<li>
<strong><{$product.name}></strong> -
<span class="price">$<{$product.price|number_format:2}></span>
<{if $product.on_sale}><span class="badge">特價</span><{/if}>
</li>
<{foreachelse}>
<li>目前無商品</li>
<{/foreach}>
</ul>
<!-- 取得索引 -->
<{foreach $items as $idx => $item}>
<div class="item-<{$idx}>"><{$item}></div>
<{/foreach}>
<{assign var="total" value=$price * $qty}>
<{assign var="fullName" value=$firstName|cat:" "|cat:$lastName}>
<{$fullName}>
<{capture name="sidebar"}>
這段內容會被捕獲到變數 $smarty.capture.sidebar
<{/capture}>
<{$smarty.capture.sidebar}>
<?php
require 'smarty_init.php';
// 模擬資料
$products = [
['id' => 1, 'name' => '筆電', 'price' => 25000, 'on_sale' => true],
['id' => 2, 'name' => '滑鼠', 'price' => 500, 'on_sale' => false],
['id' => 3, 'name' => '鍵盤', 'price' => 1200, 'on_sale' => true],
];
$user = [
'name' => '張三',
'email' => 'zhang@example.com',
'role' => 'member',
'logged_in' => true,
'created_at' => time(),
];
// 指派變數
$smarty->assign('page_title', '商品列表');
$smarty->assign('products', $products);
$smarty->assign('user', $user);
// 顯示模板
$smarty->display('index.tpl');
| 功能 | 說明 | 關鍵字 |
|---|---|---|
| 模板繼承 | 類似 Twig/Bade 的 block/extends 機制 | `{block name="content"}{/block}`、`{extends file="layout.tpl"}` |
| 快取機制 | 整頁/區塊快取,支援動態區塊 | `$smarty->caching=true`、`{nocache}{/nocache}` |
| 自訂函數 | PHP 註冊函數供模板呼叫 | `$smarty->registerPlugin('function', 'my_func', 'php_func')` |
| 自訂修飾詞 | PHP 註冊修飾詞 | `$smarty->registerPlugin('modifier', 'my_mod', 'php_mod_func')` |
| 設定檔 | ini 格式設定檔供模板讀取 | `{config_load file="settings.conf"}` |
| 內建變數 | `$smarty.now`、`$smarty.request.*`、`$smarty.session.*`、`$smarty.const.*` | 直接在模板使用 |
新專案建議考慮:
但維護舊專案時,Smarty 仍是穩定可靠的選擇,掌握其核心概念(編譯、快取、修飾詞、區塊)即可高效開發。
Smarty 入門關鍵在於:建立正確目錄權限、配置定界符避免衝突、善用修飾詞處理顯示邏輯、嚴格分離 PHP 邏輯與模板顯示。掌握 `assign`、`display`、`foreach`、`if`、`modifier` 五大核心,即可處理 90% 的模板需求。