PHP模板引擎与视图渲染
PHP本身就是模板语言。但为了更好分离视图和业务逻辑,各种模板引擎应运而生。今天说说PHP模板引擎的简单实现。
一个简单的模板引擎。
```php
class SimpleTemplate
{
private string $templateDir;
private string $cacheDir;
public function __construct(string $templateDir, string $cacheDir = '/tmp/views')
{
$this->templateDir = rtrim($templateDir, '/');
$this->cacheDir = rtrim($cacheDir, '/');
if (!is_dir($this->cacheDir)) mkdir($this->cacheDir, 0755, true);
}
public function render(string $template, array $data = []): string
{
$cacheFile = $this->cacheDir . '/' . md5($template) . '.php';
if (!file_exists($cacheFile)) {
$compiled = $this->compile($template);
file_put_contents($cacheFile, $compiled);
}
extract($data);
ob_start();
include $cacheFile;
return ob_get_clean();
}
public function compile(string $template): string
{
$content = file_get_contents($this->templateDir . '/' . $template . '.html');
$content = preg_replace('/\{\{(.+?)\}\}/', '', $content);
$content = preg_replace('/@if\((.+?)\)/', '', $content);
$content = preg_replace('/@else/', '', $content);
$content = preg_replace('/@endif/', '', $content);
$content = preg_replace('/@foreach\((.+?)\)/', '', $content);
$content = preg_replace('/@endforeach/', '', $content);
$content = preg_replace('/@php\((.+?)\)/', '', $content);
return $content;
}
}
?>
{{ $name }}的个人资料
邮箱: {{ $email }}
@if(!empty($bio))
简介: {{ $bio }}
@endif
技能
- @foreach($skills as $skill)
- {{ $skill }}
- @endforeach
$engine = new SimpleTemplate(__DIR__ . '/templates');
echo $engine->render('user', [
'name' => '张三',
'email' => 'test@test.com',
'bio' => 'PHP开发者',
'skills' => ['PHP', 'JavaScript', 'MySQL'],
]);
?>
模板编译缓存提升性能。把模板编译成PHP代码缓存起来,后续直接执行缓存的PHP文件,不需要重新解析模板。
```php
// 编译缓存
class TemplateCache
{
private string $cacheDir;
public function __construct(string $cacheDir = '/tmp/views_cache')
{
$this->cacheDir = rtrim($cacheDir, '/');
if (!is_dir($this->cacheDir)) mkdir($this->cacheDir, 0755, true);
}
public function load(string $template, array $data, callable $renderFn): string
{
$cacheKey = md5($template . serialize($data));
$cacheFile = $this->cacheDir . '/' . $cacheKey . '.html';
if (file_exists($cacheFile) && (time() - filemtime($cacheFile)) < 3600) {
return file_get_contents($cacheFile);
}
$content = $renderFn($data);
file_put_contents($cacheFile, $content);
return $content;
}
}
?>
模板引擎的核心是变量替换和模板继承。Blade、Twig这些成熟的模板引擎还支持布局、组件、指令等功能。自己做模板引擎主要是为了理解原理,生产环境建议用成熟的模板引擎。