Tpl.php
<?php
class Tpl {
//模板文件路径
protected $viewPath = './view';
//生成的缓存文件的路径
protected $cachePath = './cache';
//过期时间
protected $lifeTime = 3600;
//用来存放显示页面的数组
protected $vars = [];
public function __construct($viewPath = null, $cachePath = null, $lifeTime = null)
{
if (!empty($viewPath)) {
$this->viewPath = $viewPath;
}
$this->checkPath($this->viewPath);
if (!empty($cachePath)) {
$this->cachePath = $cachePath;
}
$this->checkPath($this->cachePath);
if (!empty($lifeTime)) {
$this->lifeTime = $lifeTime;
}
}
//需要对外公开的方法
//分配变量的方法
function assign ($key, $value) {
$this->vars[$key] = $value;
}
//展示缓存文件方法
//viewName:模板文件名
//isInclude:模板文件是仅仅需要编译,还是先编译再包含进来
//uri:index.php?page=1,为了让缓存的文件名不重复,将文件名和uri拼接起来,再md5一下,生成缓存文件,这样保证生成的缓存文件名不重复
function display ($viewName, $isInclude = true, $uri = null) {
//拼接模板文件的全路径
$viewPath = rtrim($this->viewPath, '/') . '/' . $viewName;
if (!file_exists($viewPath)) {
die('模板文件不存在');
}
//拼接缓存文件的全路径
$cacheName = md5($viewName . $uri) . '.php';
$cachePath = rtrim($this->cachePath, '/') . '/' . $cacheName;
//根据缓存文件全路径,判断缓存文件是否存在
if (!file_exists($cachePath)) {
$php = $this->compile($viewPath);
file_put_contents($cachePath, $php);
} else {
$isTimeout = !((filectime($cachePath) + $this->lifeTime) > time());
$isChange = filemtime($viewPath) > filemtime($cachePath);
if ($isTimeout || $isChange) {
$php = $this->compile($viewPath);
file_put_contents($cachePath, $php);
}
}
if ($isInclude) {
extract($this->vars);
include $cachePath;
}
//如果不存在,
//编译模板文件,生成缓存文件
//如果存在,第一个判断缓存文件是否过期
//判断模板文件是否被修改过,如果模板文件被修改过,缓存文件需要重新生成
//判断缓存文件是否需要包含进来
}
protected function checkPath ($path) {
if (!file_exists($path) || !is_dir($path)) {
return mkdir($path, 0755, true);
}
if (!is_writeable($path) || !is_readable($path)) {
return chmod($path, 0755);
}
return true;
}
protected function compile ($filePath) {
$html = file_get_contents($filePath);
$array = [
'{$%%}' => '<?=$\1; ?>',
'{foreach %%}' => '<?php foreach (\1) { ?>',
'{/foreach}' => '<?php } ?>',
'{include %%}' => '',
'{if %%}' => '<?php if (\1) ?>',
];
foreach ($array as $key => $value) {
$pattern = '#' . str_replace('%%', '(.+?)', preg_quote($key, '#')) . '#';
if (strstr($pattern, 'include')) {
$html = preg_replace_callback($pattern, [$this, 'parseInclude'], $html);
} else {
$html = preg_replace($pattern, $value, $html);
}
}
return $html;
}
protected function parseInclude ($data) {
$fileName = trim($data[1], '\'"');
$this->display($fileName, false);
$cacheName = md5($fileName) . '.php';
$cachePath = rtrim($this->cachePath, '/') . '/' . $cacheName;
return '<?php include "' . $cachePath . '"?>';
}
}
test.php
<?php
include 'Tpl.php';
$tpl = new Tpl();
$title = 'nihao';
$data = array('kebi', 'weide');
$tpl->assign('title', $title);
$tpl->assign('data', $data);
$tpl->display('test.html');
./view/test.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{$title}</title>
</head>
<body>
{foreach $data as $value}
{$value}<br />
{/foreach}
</body>
</html>