新增.语法与|函数调用,新增扩展标签库解析.语法方法

This commit is contained in:
TOP糯米 2020-07-08 16:22:49 +08:00
parent 69b409dae1
commit 78f3d5374b
12 changed files with 458 additions and 252 deletions

29
compile.php Normal file
View File

@ -0,0 +1,29 @@
<?php if (!defined('APP_PATH')) exit; ?><!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<?php $i = 0; foreach($array as $key=>$vo): $i++; echo htmlentities($vo); endforeach; ?>
将上面的内容放入raw标签
<loop from="array" to="vo">
{$vo}
</loop>
<?php $a = '张三'; ?>
{123456|md5}
<?php echo htmlentities(mb_substr($a,0,1)); if ($var == 1): echo (time()); if ($var1 == 2): echo (time()); endif; endif; ?>
扩展的标签:
<?php echo $cate['id']; ?>
默认内容,没有定义就不会覆盖我
FOOTER
</body>
</html>

View File

@ -1,27 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<?php $i = 0; foreach($array as $key=>$vo): $i++; echo ($vo); endforeach; ?>
将上面的内容放入raw标签
<volist name="array" id="vo">
<$vo>
</volist>
<?php echo ($a); if ($var == 1): echo (time()); if ($var1 == 2): echo (time()); echo $var1 == 2; endif; echo $var == 1; endif; ?>
扩展的标签:
<?php echo 'Hello'; ?>
默认内容,没有定义就不会覆盖我
FOOTER
</body>
</html>

View File

@ -1,28 +0,0 @@
<extend file="base" />
<block name="title">Document</block>
<block name="body">
<volist name="array" id="vo" index="key" key="i">
{$vo}
</volist>
将上面的内容放入raw标签
<raw>
<volist name="array" id="vo">
{$vo}
</volist>
</raw>
{$a}
<if condition="$var == 1">
{:time()}
<if condition="$var1 == 2">
{:time()}
</if>
</if>
扩展的标签:
<say what="Hello" />
</block>
<block name="footer">
FOOTER
</block>

18
engine/Article.php Normal file
View File

@ -0,0 +1,18 @@
<?php
/**
* Author: TopNuoMi
* Date: 2020/07/08
*/
class Article extends TagLib
{
public $tags = [
'list' => ['attr' => 'category-id', 'close' => 0]
];
public function _list($attr)
{
$param = $this->parseDotSyntax($attr['category-id']);
return "<?php echo {$param}; ?>";
}
}

View File

@ -1,19 +1,19 @@
<?php <?php
namespace engine;
/** /**
* 模板标签库(支持模板继承) * 模板标签解析
* Class Engine * Class Template
* @package template * @package lib
*/ */
class Engine class Engine
{ {
private static $instance;
/** /**
* @var null 单一实例 * @var array 标签定义
*/ */
private static $instance = null; protected $tags = [];
/** /**
* @var string 左定界符 * @var string 左定界符
@ -26,44 +26,41 @@ class Engine
private $right = '>'; private $right = '>';
/** /**
* @var array 标签定义 * @var array 模板配置
*/ */
protected $tags = []; private $config = [];
/** /**
* @var null 模板配置 * @var array 标签库
*/ */
protected $config = null; private $libs = [];
/** /**
* @var null 扩展标签库 * @var array 标签库类实例
*/ */
private $extend = []; private $libInstance = [];
/** /**
* @var array 扩展标签库类实例 * 获取道单一实例
* @param $config
* @return Engine
*/ */
private $extendInstance = []; public static function instance($config)
{
/** if (!self::$instance) {
* @var array 默认标签定义 self::$instance = new self($config);
*/ }
private $defaultTags = [ return self::$instance;
'php' => ['attr' => null, 'close' => 1], }
'if' => ['attr' => 'condition', 'close' => 1],
'else' => ['attr' => 'condition', 'close' => 0],
'volist' => ['attr' => 'name,index,id,key', 'close' => 1],
];
/** /**
* 构造方法 * 构造方法
* Engine constructor. * Engine constructor.
* @throws \Exception * @param array $config
*/ */
private function __construct() private function __construct($config = [])
{ {
// $this->config = Register::get('Config')->get('view'); $this->config = $config;
$this->config['dir'] = './demo/';
if (isset($this->config['left']) && $this->config['left']) { if (isset($this->config['left']) && $this->config['left']) {
$this->left = $this->config['left']; $this->left = $this->config['left'];
} }
@ -72,18 +69,6 @@ class Engine
} }
} }
/**
* 获取类单一实例
* @return null|Engine
*/
public static function instance()
{
if (!self::$instance) {
self::$instance = new self();
}
return self::$instance;
}
/** /**
* 处理模板继承 * 处理模板继承
* @param $template * @param $template
@ -91,13 +76,13 @@ class Engine
*/ */
private function parseExtend($template) private function parseExtend($template)
{ {
$pattern = '/' . $this->left . 'extend.*?file=[\'"](.*?)[\'"].*?\/' . $this->right . '/is'; $pattern = '/' . $this->left . 'extend\s+file[\s\S]*?=[\s\S]*?[\'"](.*?)[\'"][\s\S]*?\/' . $this->right . '/is';
preg_match($pattern, $template, $matches); preg_match($pattern, $template, $matches);
if (!empty($matches)) { if (!empty($matches)) {
$blockPattern = '/' . $this->left . 'block.*?name=[\'"](.*?)[\'"]' . $this->right; $blockPattern = '/' . $this->left . 'block\s+name[\s\S]*?=[\s\S]*?[\'"](.*?)[\'"][\s\S]*?' . $this->right;
$blockPattern .= '([\s\S]*?)' . $this->left . '\/block' . $this->right . '/is'; $blockPattern .= '([\s\S]*?)' . $this->left . '\/block' . $this->right . '/is';
// 获得被继承的模板内容 // 获得被继承的模板内容
$file = $this->config['dir'] . $matches[1] . '.html'; $file = $this->config['dir'] . $matches[1] . '.' . ltrim($this->config['ext'], '.');
$extendFileContent = null; $extendFileContent = null;
if (file_exists($file)) { if (file_exists($file)) {
$extendFileContent = file_get_contents($file); $extendFileContent = file_get_contents($file);
@ -144,10 +129,10 @@ class Engine
*/ */
private function parseInclude($template) private function parseInclude($template)
{ {
$pattern = '/' . $this->left . 'include.*?file=[\'"](.*?)[\'"].*?\/' . $this->right . '/is'; $pattern = '/' . $this->left . 'include\s+file[\s\S]*?=[\s\S]*?[\'"](.*?)[\'"][\s\S]*?\/' . $this->right . '/is';
$template = preg_replace_callback($pattern, function ($result) { $template = preg_replace_callback($pattern, function ($result) {
$string = null; $string = null;
$file = $this->config['dir'] . $result[1] . '.html'; $file = $this->config['dir'] . $result[1] . '.' . ltrim($this->config['ext'], '.');
if (file_exists($file)) { if (file_exists($file)) {
$string = file_get_contents($file); $string = file_get_contents($file);
} }
@ -167,7 +152,7 @@ class Engine
*/ */
private function hasInclude($template) private function hasInclude($template)
{ {
$pattern = '/' . $this->left . 'include.*?file=[\'"](.*?)[\'"].*?\/' . $this->right . '/is'; $pattern = '/' . $this->left . 'include\s+file[\s\S]*?=[\s\S]*?[\'"](.*?)[\'"][\s\S]*?\/' . $this->right . '/is';
preg_match($pattern, $template, $matches); preg_match($pattern, $template, $matches);
return !empty($matches); return !empty($matches);
} }
@ -183,78 +168,147 @@ class Engine
$search = []; $search = [];
$replace = []; $replace = [];
for ($i = 0; $i < count($matches[0]); $i++) { for ($i = 0; $i < count($matches[0]); $i++) {
$start = substr($matches[1][$i], 0, 1); $start = mb_substr($matches[1][$i], 0, 1, 'utf8');
$search[] = $matches[0][$i]; $end = mb_substr($matches[1][$i], -1, null, 'utf8');
if ($start == '$') { if ($start == '$') { // 输出变量
$replace[] = '<?php echo (' . $matches[1][$i] . '); ?>'; $search[] = $matches[0][$i];
} elseif ($start == ':') { $output = $this->parseParameterOutput($matches[1][$i]);
$replace[] = '<?php echo htmlentities(' . $output . '); ?>';
} elseif ($start == ':') { // 调用函数
$search[] = $matches[0][$i];
$replace[] = '<?php echo (' . ltrim($matches[1][$i], ':') . '); ?>'; $replace[] = '<?php echo (' . ltrim($matches[1][$i], ':') . '); ?>';
} else { } elseif ($start == '@') { // 输出常量
$replace[] = $matches[0][$i]; $search[] = $matches[0][$i];
$replace[] = '<?php echo htmlentities(' . ltrim($matches[1][$i], '@') . '); ?>';
} elseif ($start == '*' && $end == '*') { // 注释
$search[] = $matches[0][$i];
$replace[] = '<?php /* ' . trim($matches[1][$i], '*') . ' */ ?>';
} }
} }
$template = str_replace($search, $replace, $template); if (!empty($search) && !empty($replace)) {
$template = str_replace($search, $replace, $template);
}
return $template; return $template;
} }
/** /**
* 外部加载扩展标签 * 解析变量输出
* @param $lib * @param $output
* @return string
*/ */
public function loadTaglib($lib) private function parseParameterOutput($output)
{ {
$this->extend[] = $lib; // 处理|函数调用
if (strstr($output, '|')) {
$functions = explode('|', $output);
$parse = $functions[0];
// 只留下函数表达式
unset($functions[0]);
// 重置调用函数数组索引以便开始foreach循环
$functions = array_values($functions);
foreach ($functions as $function) {
$expParameters = explode('=', $function);
$functionName = $expParameters[0];
// 如果有带上参数,则进行参数处理,没有声明参数则直接将当前值作为函数的第一个参数
if (isset($expParameters[1])) {
$parameters = $expParameters[1];
// 如果有参数,则处理,同时将占位符###替换为上次解析结果
// 如果存在占位符,则直接替换,没有占位符则将当前值作为函数的第一个参数
if (strstr($expParameters[1], '###')) {
$parse = $functionName . '(' . str_replace('###', $parse, $parameters) . ')';
} else {
$parse = $functionName . '(' . $parse . ',' . $parameters . ')';
}
} else {
$parse = $functionName . '(' . $parse . ')';
}
}
$output = $parse;
}
return $this->parseDotSyntax($output);
} }
/** /**
* 标签处理 * 处理.语法
* @param $template * @param $string
* @return null|string|string[] * @return null|string|string[]
*/ */
private function parseTags($template) private function parseDotSyntax($string)
{ {
foreach ($this->extend as $lib) { // 处理.语法(仅数组或已实现数组访问接口的对象)
$this->extendInstance[$lib] = $object = new $lib; return preg_replace_callback("/\.([a-zA-Z0-9_-]*)/", function ($match) {
if (isset($match[1])) {
return '[' . (is_numeric($match[1]) ? $match[1] : '\'' . $match[1] . '\'') . ']';
} else {
return null;
}
}, $string);
}
/**
* 外部加载扩展标签
* @param $prefix
* @param $className
*/
public function loadTaglib($prefix, $className)
{
if ($prefix == 'default') {
throw new \Exception('扩展标签库前缀不能为default');
}
$this->libs[$prefix] = $className;
}
/**
* 获取所有标签
* @return null|string|string[]
*/
private function getTags()
{
$tags = [];
// 加入默认标签库
$this->libs = array_merge(['default' => Tags::class,], $this->libs);
foreach ($this->libs as $prefix => $lib) {
$this->libInstance[$prefix] = $object = new $lib;
foreach ($object->tags as $name => $tag) { foreach ($object->tags as $name => $tag) {
if (!isset($this->tags[$name]) && !isset($this->defaultTags[$name])) { if (!isset($tags[$name])) { // 如果不存在则加入到标签库
$this->tags[$name] = $tag; $tags[($prefix == 'default' ? '' : $prefix . ':') . $name] = $tag;
} }
} }
} }
$tags = array_merge($this->defaultTags, $this->tags); return $tags;
return $this->_parseTags($template, $tags);
} }
/** /**
* 获取标签处理结果 * 获取标签处理结果
* @param $method * @param $name
* @param $tag * @param $attr
* @param string $content * @param string $content
* @return null * @return mixed
*/ */
private function getTagParseResult($method, $tag, $content = '') private function getTagParseResult($name, $attr, $content = '')
{ {
if (method_exists($this, $method)) { // 如果是扩展标签则找到扩展类进行处理
return $this->{$method}($tag, $content); if (strstr($name, ':')) {
} else { $tagInfo = explode(':', $name);
foreach ($this->extendInstance as $item) { if (method_exists($this->libInstance[$tagInfo[0]], '_' . $tagInfo[1])) {
if (method_exists($item, $method)) { return $this->libInstance[$tagInfo[0]]->{'_' . $tagInfo[1]}($attr, $content);
return $item->{$method}($tag, $content);
}
} }
return null; } // 否则尝试默认标签处理
else if (method_exists($this->libInstance['default'], '_' . $name)) {
return $this->libInstance['default']->{'_' . $name}($attr, $content);
} }
} }
/** /**
* 进行标签处理 * 进行标签处理
* @param $template * @param $template
* @param $tags
* @return null|string|string[] * @return null|string|string[]
*/ */
private function _parseTags($template, $tags) private function parseTags($template)
{ {
foreach ($tags as $name => $item) { foreach ($this->getTags() as $name => $item) {
$pattern = '/' . $this->left . '(?:(' . $name . ')\b(?>[^' . $this->right . ']*)|\/(' . $name . '))'; $pattern = '/' . $this->left . '(?:(' . $name . ')\b(?>[^' . $this->right . ']*)|\/(' . $name . '))';
$pattern .= $this->right . '/is'; $pattern .= $this->right . '/is';
if ($item['close']) { if ($item['close']) {
@ -284,12 +338,15 @@ class Engine
if (!empty($nodes)) { if (!empty($nodes)) {
$nodes = array_merge($nodes, []); $nodes = array_merge($nodes, []);
$cut = '<!--CONTENT-->'; $cut = '<!--CONTENT-->';
$method = '_' . $name;
$startArray = []; $startArray = [];
foreach ($nodes as $pos => $node) { foreach ($nodes as $pos => $node) {
$attr = $item['attr'] ? $this->getAttr($node['start_str'], explode(',', $item['attr'])) : []; $attr = $item['attr'] ? $this->getAttr($node['start_str'], explode(',', $item['attr'])) : [];
// 得到准备替换的值 // 得到准备替换的值
$replace = explode($cut, $this->getTagParseResult($method, $attr, $cut)); $replace = explode($cut, $this->getTagParseResult($name, $attr, $cut));
$replace = [
(isset($replace[0])) ? $replace[0] : [],
(isset($replace[1])) ? $replace[1] : [],
];
while ($startArray) { while ($startArray) {
$begin = end($startArray); $begin = end($startArray);
// 如果当前结束位置大于最后一个开始标签的位置,则跳过,直接去替换这个结束标签 // 如果当前结束位置大于最后一个开始标签的位置,则跳过,直接去替换这个结束标签
@ -308,7 +365,7 @@ class Engine
'string' => $replace[0] 'string' => $replace[0]
]; ];
} }
// 替换掉最后入栈未进入while循环的开始标签 // 替换没有结束标签穿插的开始标签
while ($startArray) { while ($startArray) {
$begin = array_pop($startArray); $begin = array_pop($startArray);
$template = substr_replace($template, $begin['string'], $begin['start'], $begin['length']); $template = substr_replace($template, $begin['string'], $begin['start'], $begin['length']);
@ -316,14 +373,16 @@ class Engine
} }
} }
} else { // 自闭合标签处理 } else { // 自闭合标签处理
$template = preg_replace_callback($pattern, function ($matches) use ($item) { $template = preg_replace_callback($pattern, function ($matches) use ($name, $item) {
$method = '_' . $matches[1]; if (!isset($matches[2])) {
$attr = $item['attr'] ? $this->getAttr($matches[0], explode(',', $item['attr'])) : []; $attr = $item['attr'] ? $this->getAttr($matches[0], explode(',', $item['attr'])) : [];
return $this->getTagParseResult($method, $attr); return $this->getTagParseResult($name, $attr);
}
return $matches[0];
}, $template); }, $template);
} }
} }
return preg_replace('/\?>([\r|\n|\s]*?)<\?php/is', '', $template); return $template;
} }
/** /**
@ -335,13 +394,13 @@ class Engine
private function getAttr($string, $tags = []) private function getAttr($string, $tags = [])
{ {
$attr = []; $attr = [];
$attrPattern = '/[ +](.*?)=[\'"](.*?)[\'"]/is'; $attrPattern = '/\s+(.*?)=[\s\S]*?([\'"])(.*?)\\2/is';
preg_match_all($attrPattern, $string, $result); preg_match_all($attrPattern, $string, $result);
if (isset($result[0]) && !empty($result[0])) { if (isset($result[0]) && !empty($result[0])) {
foreach ($result[1] as $key => $value) { foreach ($result[1] as $key => $value) {
$name = trim($value, ' '); $name = str_replace([' ', "\t", PHP_EOL], '', $value);
if (in_array($name, $tags)) { if (in_array($name, $tags)) {
$attr[$name] = $result[2][$key]; $attr[$name] = $result[3][$key];
} }
} }
} }
@ -349,97 +408,39 @@ class Engine
} }
/** /**
* 处理raw标签 * 处理original标签
* @param $template * @param $template
* @return null|string|string[] * @return null|string|string[]
*/ */
private function parseRaw($template) private function parseOriginal($template)
{ {
$pattern = '/' . $this->left . 'raw' . $this->right . '([\s\S]*?)'; $pattern = '/' . $this->left . 'original' . $this->right . '([\s\S]*?)';
$pattern .= $this->left . '\/raw' . $this->right . '/is'; $pattern .= $this->left . '\/original' . $this->right . '/is';
$template = preg_replace_callback($pattern, function ($matches) { return preg_replace_callback($pattern, function ($matches) {
return str_replace([ return str_replace([
$this->left, $this->right, $this->left, $this->right,
'{', '}' '{', '}'
], [ ], [
'<RAW!--', '--RAW>', '<!ORIGINAL--', '--ORIGINAL>',
'<RAW!--', '--RAW>' '<!PARAM--', '--PARAM>'
], $matches[1]); ], $matches[1]);
}, $template); }, $template);
return $template;
} }
/** /**
* 还原raw * 还原original内容
* @param $template * @param $template
* @return mixed * @return mixed
*/ */
public function returnRaw($template) private function returnOriginal($template)
{ {
$template = str_replace([ return str_replace([
'<RAW!--', '--RAW>', '<!ORIGINAL--', '--ORIGINAL>',
'<RAW!--', '--RAW>' '<!PARAM--', '--PARAM>'
], [ ], [
$this->left, $this->right, $this->left, $this->right,
'{', '}' '{', '}'
], $template); ], $template);
return $template;
}
/**
* php标签开始
* @param $tag
* @param $content
* @return string
*/
private function _php($tag, $content)
{
return '<?php ' . $content . ' ?>';
}
/**
* if标签
* @param $tag
* @param $content
* @return string
*/
private function _if($tag, $content)
{
$parse = '<?php if (' . $tag['condition'] . '): ?>';
$parse .= $content;
$parse .= '<?php echo ' . $tag['condition'] . '; endif; ?>';
return $parse;
}
/**
* else标签
* @param $tag
* @return string
*/
private function _else($tag)
{
if (isset($tag['condition'])) {
$parse = '<?php elseif (' . $tag['condition'] . '): ?>';
} else {
$parse = '<?php else: ?>';
}
return $parse;
}
/**
* volist标签
* @param $tag
* @param $content
* @return string
*/
private function _volist($tag, $content)
{
$parse = '<?php ' . (isset($tag['key']) ? '$' . $tag['key'] . ' = 0; ' : '');
$parse .= 'foreach($' . $tag['name'] . ' as ' . (isset($tag['index']) ? '$' . $tag['index'] . '=>' : '') . '$' . $tag['id'] . '): ';
$parse .= (isset($tag['key']) ? '$' . $tag['key'] . '++;' : '') . ' ?>';
$parse .= $content;
$parse .= '<?php endforeach; ?>';
return $parse;
} }
/** /**
@ -449,18 +450,22 @@ class Engine
*/ */
public function compile($template) public function compile($template)
{ {
// 处理raw标签 // 处理original标签
$template = $this->parseRaw($template); $template = $this->parseOriginal($template);
// 处理模板继承标签 // 处理模板继承标签
$template = $this->parseExtend($template); $template = $this->parseExtend($template);
// 处理include标签 // 处理include标签
$template = $this->parseInclude($template); $template = $this->parseInclude($template);
// 处理变量以及函数
$template = $this->parseVars($template);
// 处理定义的标签 // 处理定义的标签
$template = $this->parseTags($template); $template = $this->parseTags($template);
// 处理变量以及函数
$template = $this->parseVars($template);
// 还原original内容
$template = $this->returnOriginal($template);
// 清除多余开始结束标签
$template = preg_replace('/\?>([\r|\n|\s]*?)<\?php/is', '', $template);
return $template; return '<?php if (!defined(\'APP_PATH\')) exit; ?>' . $template;
} }
} }

View File

@ -1,16 +0,0 @@
<?php
namespace engine;
class Extend
{
public $tags = [
'say' => ['attr' => 'what', 'close' => 0]
];
public function _say($tag)
{
return '<?php echo \''. $tag['what'] .'\'; ?>';
}
}

23
engine/TagLib.php Normal file
View File

@ -0,0 +1,23 @@
<?php
abstract class TagLib
{
public $tags = [];
/**
* 处理点语法
* @param $string
* @return null|string|string[]
*/
protected function parseDotSyntax($string)
{
// 处理.语法(仅数组或已实现数组访问接口的对象)
return preg_replace_callback("/\.([a-zA-Z0-9_-]*)/", function ($match) {
if (isset($match[1])) {
return '[' . (is_numeric($match[1]) ? $match[1] : '\'' . $match[1] . '\'') . ']';
} else {
return null;
}
}, $string);
}
}

161
engine/Tags.php Normal file
View File

@ -0,0 +1,161 @@
<?php
/**
* 自带标签库
*/
class Tags extends TagLib
{
/**
* 标签描述
* @var array
*/
public $tags = [
'php' => ['attr' => '', 'close' => 1],
'if' => ['attr' => 'condition', 'close' => 1],
'else' => ['attr' => 'condition', 'close' => 0],
'loop' => ['attr' => 'from,to,index,key', 'close' => 1],
'assign' => ['attr' => 'name,value', 'close' => 0],
'switch' => ['attr' => 'name', 'close' => 1],
'case' => ['attr' => 'value', 'close' => 1],
];
/**
* php标签
* @param $attr
* @param $content
* @return string
*/
public function _php($attr, $content)
{
return '<?php ' . $content . ' ?>';
}
/**
* if标签
* @param $attr
* @param $content
* @return string
*/
public function _if($attr, $content)
{
$attr['condition'] = $this->_parseCondition($attr['condition']);
$parse = '<?php if (' . $attr['condition'] . '): ?>';
$parse .= $content;
$parse .= '<?php endif; ?>';
return $parse;
}
/**
* else标签
* @param $attr
* @return string
*/
public function _else($attr)
{
if (isset($attr['condition'])) {
$attr['condition'] = $this->_parseCondition($attr['condition']);
$parse = '<?php elseif (' . $attr['condition'] . '): ?>';
} else {
$parse = '<?php else: ?>';
}
return $parse;
}
/**
* loop标签
* @param $attr
* @param $content
* @return string
*/
public function _loop($attr, $content)
{
$parse = '<?php ' . (isset($attr['key']) ? '$' . $attr['key'] . ' = 0; ' : '');
$parse .= 'foreach($' . $attr['from'] . ' as ' . (isset($attr['index']) ? '$' . $attr['index'] . '=>' : '') . '$' . $attr['to'] . '): ';
$parse .= (isset($attr['key']) ? '$' . $attr['key'] . '++;' : '') . ' ?>';
$parse .= $content;
$parse .= '<?php endforeach; ?>';
return $parse;
}
/**
* 模版变量赋值
* @param $attr
* @return string
*/
public function _assign($attr)
{
if (isset($attr['name']) && isset($attr['value'])) {
$quot = (strstr($attr['value'], '\'')) ? '"' : '\'';
$parse = '<?php $' . $attr['name'] . ' = ' . (is_numeric($attr['value']) ? $attr['value'] : $quot . $attr['value'] . $quot) . '; ?>';
return $parse;
}
throw new \Exception('assign标签必须拥有属性' . $this->defaultTags['assign']['attr']);
}
/**
* switch标签
* @param $attr
* @param $content
* @return string
*/
public function _switch($attr, $content)
{
if (isset($attr['name'])) {
$parse = '<?php switch ($' . $attr['name'] . '): ?>';
$parse .= $content;
$parse .= '<?php endswitch; ?>';
return $parse;
}
throw new \Exception('switch标签必须拥有属性' . $this->defaultTags['switch']['attr']);
}
/**
* switch标签case处理
* @param $attr
* @param $content
* @return string
*/
public function _case($attr, $content)
{
if (isset($attr['value'])) {
$quot = (strstr($attr['value'], '\'')) ? '"' : '\'';
$parse = '<?php case ' . $quot . $attr['value'] . $quot . ': ?>';
$parse .= $content;
$parse .= '<?php break; ?>';
} else {
$parse = '<?php default: ?>';
$parse .= $content;
}
return $parse;
}
/**
* 处理if/else标签的条件比较符
* @param $condition
* @return mixed
*/
private function _parseCondition($condition)
{
return str_ireplace([
' eq ',
' neq ',
' lt ',
' elt ',
' gt ',
' egt ',
' heq ',
' nheq '
], [
' == ',
' != ',
' < ',
' <= ',
' > ',
' >= ',
' === ',
' !== '
], $condition);
}
}

View File

@ -1,17 +1,28 @@
<?php <?php
require 'engine/Engine.php'; require 'engine/Engine.php';
require 'engine/Extend.php'; require 'engine/TagLib.php';
require 'engine/Tags.php';
require 'engine/Article.php';
$content = file_get_contents('./demo/index.html');
$t1 = microtime(true); $t1 = microtime(true);
$template = \engine\Engine::instance();
// 加载自定义标签库
$template->loadTaglib(\engine\Extend::class);
// 编译
$result = $template->compile($content);
// 最后还原raw标签
$result = $template->returnRaw($result);
$t2 = microtime(true);
echo '执行时间' . ($t2 - $t1) . "\r\n";
file_put_contents(md5(time()) . '.php', $result); // 获取模板引擎实例
$config = [
'ext' => 'html',
'dir' => './view/',
'left' => '<',
'right' => '>',
];
$engine = Engine::instance($config);
// 加载自定义标签库
$engine->loadTaglib('article', Article::class);
// 读取模板内容
$template = file_get_contents('./view/index.html');
// 编译并写入
$content = $engine->compile($template);
file_put_contents('compile.php', $content);
$t2 = microtime(true);
echo '运行时间:' . ($t2 - $t1);

30
view/index.html Normal file
View File

@ -0,0 +1,30 @@
<extend file="base"/>
<block name="title">Document</block>
<block name="body">
<loop from="array" to="vo" index="key" key="i">
{$vo}
</loop>
将上面的内容放入raw标签
<original>
<loop from="array" to="vo">
{$vo}
</loop>
</original>
<assign name="a" value="张三"/>
{123456|md5}
{$a|mb_substr=0,1}
<if condition="$var eq 1">
{:time()}
<if condition="$var1 eq 2">
{:time()}
</if>
</if>
扩展的标签:
<article:list category-id="$cate.id"/>
</block>
<block name="footer">
FOOTER
</block>