如果你不想用 ThinkPHP 5、Laravel 这些自带模板系统,只想用 PHP 原生写一个“最简单的模板引擎”,其实非常容易。
下面给你一个:
✅ 仅 50 行
✅ 支持变量替换
✅ 支持 if
✅ 支持 foreach
✅ 无依赖
✅ 适合学习原理
一、最最简单版本(变量替换版)
模板文件 view.html
<h1>{{title}}</h1>
<p>欢迎你,{{name}}</p>
模板引擎类 Template.php
<?php
class Template
{
protected $vars = [];
public function assign($key, $value)
{
$this->vars[$key] = $value;
}
public function render($file)
{
$content = file_get_contents($file);
foreach ($this->vars as $key => $value) {
$content = str_replace('{{'.$key.'}}', $value, $content);
}
echo $content;
}
}
使用方式
require 'Template.php';
$tpl = new Template();
$tpl->assign('title', '我的首页');
$tpl->assign('name', '张三');
$tpl->render('view.html');
二、升级版(支持 if / foreach)
我们做一个“超轻量编译型模板引擎”。
原理:
把模板语法转换成 PHP 代码,然后 include 执行。
1️⃣ 模板文件 view.html
<h1>{$title}</h1>
{if $age >= 18}
<p>你是成年人</p>
{else}
<p>你是未成年</p>
{/if}
<ul>
{foreach $list as $item}
<li>{$item}</li>
{/foreach}
</ul>
2️⃣ 模板引擎
<?php
class Template
{
protected $vars = [];
protected $cachePath = 'cache/';
public function assign($key, $value)
{
$this->vars[$key] = $value;
}
public function render($file)
{
$cacheFile = $this->cachePath . md5($file) . '.php';
// 如果缓存不存在或模板更新
if (!file_exists($cacheFile) || filemtime($file) > filemtime($cacheFile)) {
$content = file_get_contents($file);
$compiled = $this->compile($content);
file_put_contents($cacheFile, $compiled);
}
extract($this->vars);
include $cacheFile;
}
protected function compile($content)
{
$content = preg_replace('/\{\$(.*?)\}/', '<?php echo $1; ?>', $content);
$content = preg_replace('/\{if (.*?)\}/', '<?php if($1): ?>', $content);
$content = preg_replace('/\{else\}/', '<?php else: ?>', $content);
$content = preg_replace('/\{\/if\}/', '<?php endif; ?>', $content);
$content = preg_replace('/\{foreach (.*?)\}/', '<?php foreach($1): ?>', $content);
$content = preg_replace('/\{\/foreach\}/', '<?php endforeach; ?>', $content);
return $content;
}
}
3️⃣ 使用
$tpl = new Template();
$tpl->assign('title', '测试页面');
$tpl->assign('age', 20);
$tpl->assign('list', ['苹果', '香蕉', '橙子']);
$tpl->render('view.html');
三、运行原理图
模板文件
↓
正则替换
↓
生成 PHP 文件
↓
include 执行
↓
输出 HTML
这就是:
Smarty
Blade
ThinkPHP 模板
的核心原理。
四、安全加强版(防 XSS)
上面的变量输出是不安全的:
<?php echo $name; ?>
应该改成:
<?php echo htmlspecialchars($name, ENT_QUOTES, 'UTF-8'); ?>
修改编译规则:
$content = preg_replace(
'/\{\$(.*?)\}/',
'<?php echo htmlspecialchars($1, ENT_QUOTES, "UTF-8"); ?>',
$content
);
五、再进阶你可以加
| 功能 | 做法 |
|---|---|
| 模板继承 | block 解析 |
| include 子模板 | include 编译 |
| layout 布局 | 先解析内容块 |
| 缓存时间 | 判断 filemtime |
| 自定义函数 | 注册函数表 |
六、如果你只是想要“最简单”
其实最简单就是:
extract($data);
include 'view.php';
直接在 view.php 里写:
<h1><?= $title ?></h1>
这就是:
PHP 本身就是模板引擎。
七、对比主流模板引擎
| 引擎 | 特点 |
|---|---|
| Smarty | 经典模板引擎 |
| Twig | 安全严格 |
| Blade | Laravel 专用 |
| 原生自写 | 最轻量 |
八、结论
如果是:
- 小项目 → 原生 include 就够
- 中型项目 → 自写编译型模板
- 大项目 → 用成熟模板引擎
如果你愿意,我可以给你:
- 🔥 100 行实现一个“类 Smarty”模板引擎
- 🔥 支持模板继承的完整版
- 🔥 带缓存优化的生产级模板
- 🔥 MVC 框架最小实现(自写 PHP 框架)
你是想学习原理,还是想做一个可商用的轻量框架?
发表回复