
本文介绍如何在 smarty 模板引擎中实现“按需分配变量”,避免在主入口文件中集中管理所有页面变量,通过分离页面逻辑与模板渲染,提升代码可维护性与可扩展性。
本文介绍如何在 smarty 模板引擎中实现“按需分配变量”,避免在主入口文件中集中管理所有页面变量,通过分离页面逻辑与模板渲染,提升代码可维护性与可扩展性。
在使用 Smarty 构建基于 $_GET['page'] 路由的单入口 Web 应用时,一个常见痛点是:将所有页面的变量(如 title、varA、varID)全部堆砌在 index.php 中,导致逻辑混乱、难以维护,且违背关注点分离原则。理想方案应是——每个页面(如 Home、Create)拥有专属的变量初始化逻辑,与模板一一对应,互不干扰。
✅ 推荐实践:页面专属 PHP 控制器文件
Smarty 本身不提供自动按模板名加载对应变量逻辑的功能(例如访问 ?page=Home 时自动执行 Home.php),但可通过轻量级约定 + PHP include 实现清晰解耦。核心思路是:主入口(index.php)负责初始化 Smarty 实例与公共配置;各页面由独立 .php 文件负责分配其专属变量并调用 display()。
示例结构
/ ├── index.php ← 主入口,初始化 Smarty ├── home.php ← Home 页面逻辑(assign + display) ├── create.php ← Create 页面逻辑 ├── templates/ │ ├── Home.tpl │ └── Create.tpl ├── templates_c/ ← 编译缓存目录(自动生成) └── cache/ ← 运行时缓存目录(可选)
index.php(精简版)
<?php
require 'smarty-4.2.0/libs/Smarty.class.php';
$smarty = new Smarty();
$smarty->setTemplateDir('templates');
$smarty->setCompileDir('templates_c');
$smarty->setCacheDir('cache');
$smarty->setConfigDir('configs');
// 公共变量(所有页面共享)
$smarty->assign('site_name', 'My App');
// 路由分发:根据 $_GET['page'] 加载对应控制器
$page = $_GET['page'] ?? 'home';
switch ($page) {
case 'home':
include 'home.php';
break;
case 'create':
include 'create.php';
break;
default:
$smarty->assign('title', '404 Not Found');
$smarty->display('error.tpl');
exit;
}
home.php(页面专属逻辑)
<?php
// 此处仅处理 Home 页面所需变量
$smarty->assign('title', 'Home page');
$smarty->assign('varA', 'text text text');
// 渲染对应模板(注意:.tpl 后缀已由 Smarty 自动补全)
$smarty->display('Home.tpl');create.php
<?php
$smarty->assign('title', 'Create page');
$smarty->assign('varID', 33442222244);
$smarty->display('Create.tpl');? 关于 templates_c/ 目录的说明
templates_c/ 是 Smarty 的编译缓存目录,并非手动维护的 PHP 文件存放地。当 Smarty 首次解析 Home.tpl 时,会将其编译为高度优化的原生 PHP 代码(如 Home.tpl.php),并存入该目录。后续请求直接执行此编译后文件,大幅提升性能。
⚠️ 注意:
-
你无需、也不应手动编辑
templates_c/中的文件——它们由 Smarty 自动生成与更新; -
cache/目录用于存储开启caching = true后的完整 HTML 输出缓存,与templates_c/的编译缓存职责不同; - 若修改了
.tpl模板,Smarty 在开发模式下($smarty->debugging = true;或force_compile = true)会自动重新编译,确保模板变更即时生效。
✅ 最佳实践建议
-
命名一致性:PHP 控制器文件(
home.php)与模板文件(Home.tpl)保持语义关联,便于团队理解; -
错误防御:在
switch中加入default分支,防止非法page参数导致白屏; -
安全加固:对
$_GET['page']做白名单校验(如in_array($page, ['home','create'])),禁止路径遍历或任意文件包含; - 进阶方向:未来可封装为简易路由类或集成 PSR-7 兼容框架(如 Slim + Smarty),进一步标准化。
通过这种“主入口初始化 + 页面控制器分离”的模式,你既能享受 Smarty 强大的模板隔离能力,又能保持 PHP 业务逻辑的清晰分层——告别变量大杂烩,拥抱可维护的模板工程化实践。

















