From a2e2602c59c7a6e7d16b78e4a4cd3dbd29a1f617 Mon Sep 17 00:00:00 2001
From: topnuomi <1130395124@qq.com>
Date: Sun, 28 Jul 2019 16:06:38 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=8A=A0=E8=BD=BD=E8=87=AA?=
=?UTF-8?q?=E5=AE=9A=E4=B9=89=E6=A0=87=E7=AD=BE=E5=BA=93=E7=9A=84=E6=96=B9?=
=?UTF-8?q?=E5=BC=8F?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
...hp => 2ec7facf63614beb8c7f02cc2378e1cd.php | 4 +-
demo/index.html | 4 +
script.php | 25 +-
template/Engine.php | 346 +++++++++---------
template/Extend.php | 8 +-
5 files changed, 194 insertions(+), 193 deletions(-)
rename aa7cc8f2dc7ba35fd85943e9db00190b.php => 2ec7facf63614beb8c7f02cc2378e1cd.php (66%)
diff --git a/aa7cc8f2dc7ba35fd85943e9db00190b.php b/2ec7facf63614beb8c7f02cc2378e1cd.php
similarity index 66%
rename from aa7cc8f2dc7ba35fd85943e9db00190b.php
rename to 2ec7facf63614beb8c7f02cc2378e1cd.php
index 5688f9f..60952c6 100644
--- a/aa7cc8f2dc7ba35fd85943e9db00190b.php
+++ b/2ec7facf63614beb8c7f02cc2378e1cd.php
@@ -6,14 +6,14 @@
-
+
将上面的内容放入raw标签:
{$vo}
-
+
扩展的标签:
diff --git a/demo/index.html b/demo/index.html
index 439f66b..bcb1431 100644
--- a/demo/index.html
+++ b/demo/index.html
@@ -12,8 +12,12 @@
{$vo}
+ {$a}
{:time()}
+
+ {:time()}
+
扩展的标签:
diff --git a/script.php b/script.php
index a3b74d3..5dfe2b9 100644
--- a/script.php
+++ b/script.php
@@ -3,24 +3,15 @@ require 'template/Engine.php';
require 'template/Extend.php';
$content = file_get_contents('./demo/index.html');
-
-echo "\r\n\r\n原始内容\r\n\r\n";
-print_r($content);
-
-$template = new \template\Engine();
-// 默认编译结果
+$t1 = microtime(true);
+$template = \template\Engine::instance();
+// 加载自定义标签库
+$template->loadTaglib(\template\Extend::class);
+// 编译
$result = $template->compile($content);
-
-echo "\r\n\r\n第一次结果\r\n\r\n";
-print_r($result);
-
-// 开始处理用户定义标签库
-$extend = new \template\Extend();
-$result = $extend->parseCustomizeTags($result);
-// 用户定义标签库处理结束
-
// 最后还原raw标签
$result = $template->returnRaw($result);
+$t2 = microtime(true);
+echo '执行时间' . ($t2 - $t1) . "\r\n";
-echo "\r\n\r\n第二次结果\r\n\r\n";
-print_r($result);
+file_put_contents(md5(time()) . '.php', $result);
\ No newline at end of file
diff --git a/template/Engine.php b/template/Engine.php
index 8d0e4ea..3c8bbdc 100644
--- a/template/Engine.php
+++ b/template/Engine.php
@@ -9,6 +9,12 @@ namespace template;
*/
class Engine
{
+
+ /**
+ * @var null 单一实例
+ */
+ private static $instance = null;
+
/**
* @var string 左定界符
*/
@@ -28,23 +34,26 @@ class Engine
* @var null 模板配置
*/
protected $config = null;
-
+
/**
- * @var null 模板路径
+ * @var null 扩展标签库
*/
- private $viewDir = null;
+ private $extend = [];
+
+ /**
+ * @var array 扩展标签库类实例
+ */
+ private $extendInstance = [];
/**
* @var array 默认标签定义
*/
private $defaultTags = [
+ 'php' => ['attr' => null, 'close' => 1],
'if' => ['attr' => 'condition', 'close' => 1],
'else' => ['attr' => 'condition', 'close' => 0],
'volist' => ['attr' => 'name,id,key', 'close' => 1],
- 'assign' => ['attr' => 'name,value', 'close' => 0],
- 'switch' => ['attr' => 'name', 'close' => 1],
- 'case' => ['attr' => 'value', 'close' => 1],
- 'default' => ['attr' => '', 'close' => 1]
+ 'assign' => ['attr' => 'name,value', 'close' => 0]
];
/**
@@ -52,24 +61,44 @@ class Engine
* Engine constructor.
* @throws \Exception
*/
- public function __construct()
+ private function __construct()
{
- // 仅作示例,请在外部传入模板目录
- $this->viewDir = './demo/';
+ // $this->config = Register::get('Config')->get('view');
+ $this->config['dir'] = './demo/';
+ if (isset($this->config['left']) && $this->config['left']) {
+ $this->left = $this->config['left'];
+ }
+ if (isset($this->config['right']) && $this->config['right']) {
+ $this->right = $this->config['right'];
+ }
+ }
+
+ /**
+ * 获取类单一实例
+ * @return null|Engine
+ */
+ public static function instance()
+ {
+ if (!self::$instance) {
+ self::$instance = new self();
+ }
+ return self::$instance;
}
/**
* 处理模板继承
+ * @param $template
+ * @return mixed
*/
- private function parseExtend($tmpl)
+ private function parseExtend($template)
{
$pattern = '#' . $this->left . 'extend +file=[\'"](.*?)[\'"] +/' . $this->right . '#';
- preg_match($pattern, $tmpl, $matches);
+ preg_match($pattern, $template, $matches);
if (!empty($matches)) {
$blockPattern = '#' . $this->left . 'block +name=[\'"](.*?)[\'"]' . $this->right;
$blockPattern .= '([\s\S]*?)' . $this->left . '\/block' . $this->right . '#';
// 获得被继承的模板内容
- $file = $this->viewDir . $matches[1] . '.html';
+ $file = $this->config['dir'] . $matches[1] . '.html';
$extendFileContent = null;
if (file_exists($file)) {
$extendFileContent = file_get_contents($file);
@@ -80,7 +109,7 @@ class Engine
// 被继承模板中的块
preg_match_all($blockPattern, $extendFileContent, $extendResult);
// 继承模板中的块
- preg_match_all($blockPattern, $tmpl, $templateResult);
+ preg_match_all($blockPattern, $template, $templateResult);
// 组合搜索的块数组
$search = [];
$defaultContent = [];
@@ -104,172 +133,219 @@ class Engine
$replaceArray[] = $defaultContent[$key];
}
}
- $tmpl = str_replace($searchArray, $replaceArray, $extendFileContent);
+ $template = str_replace($searchArray, $replaceArray, $extendFileContent);
}
- return $tmpl;
+ return $template;
}
/**
* 处理include标签
- * @return bool
+ * @param $template
+ * @return null|string|string[]
*/
- private function parseInclude($tmpl)
+ private function parseInclude($template)
{
$pattern = '#' . $this->left . 'include +file=[\'"](.*?)[\'"] +/' . $this->right . '#';
- $tmpl = preg_replace_callback($pattern, function ($result) {
+ $template = preg_replace_callback($pattern, function ($result) {
$str = null;
- $file = $this->viewDir . $result[1] . '.html';
+ $file = $this->config['dir'] . $result[1] . '.html';
if (file_exists($file)) {
$str = file_get_contents($file);
}
return $str;
- }, $tmpl);
+ }, $template);
// 处理多层include
- if ($this->hasInclude($tmpl)) {
- $tmpl = $this->parseInclude($tmpl);
+ if ($this->hasInclude($template)) {
+ $template = $this->parseInclude($template);
}
- return $tmpl;
+ return $template;
}
/**
* 检测是否含有include
- * @param $tmpl
+ * @param $template
* @return bool
*/
- private function hasInclude($tmpl)
+ private function hasInclude($template)
{
$pattern = '#' . $this->left . 'include +file=[\'"](.*?)[\'"] +/' . $this->right . '#';
- preg_match($pattern, $tmpl, $matches);
+ preg_match($pattern, $template, $matches);
return !empty($matches);
}
/**
* 分析参数以及函数输出
+ * @param $template
+ * @return mixed
*/
- private function parseVars($tmpl)
+ private function parseVars($template)
{
- preg_match_all('#{(.*?)}#', $tmpl, $matches);
+ preg_match_all('#{(.*?)}#', $template, $matches);
$search = [];
$replace = [];
for ($i = 0; $i < count($matches[0]); $i++) {
$start = substr($matches[1][$i], 0, 1);
+ $search[] = $matches[0][$i];
if ($start == '$') {
- $search[] = $matches[0][$i];
- $replace[] = '';
+ $replace[] = '';
} elseif ($start == ':') {
- $search[] = $matches[0][$i];
- $replace[] = '';
+ $replace[] = '';
+ } else {
+ $replace[] = $matches[0][$i];
}
}
- $tmpl = str_replace($search, $replace, $tmpl);
- return $tmpl;
+ $template = str_replace($search, $replace, $template);
+ return $template;
}
/**
- * 处理用户自定义标签
- * @param $tmpl
- * @return null|string|string[]
+ * 外部加载扩展标签
+ * @param $lib
*/
- public function parseCustomizeTags($tmpl)
+ public function loadTaglib($lib)
{
- return $this->parseTags($tmpl, $this->tags);
+ $this->extend[] = $lib;
}
/**
- * 处理默认的标签
- * @param $tmpl
+ * 标签处理
+ * @param $template
* @return null|string|string[]
*/
- private function parseDefaultTags($tmpl)
+ private function parseTags($template)
{
- return $this->parseTags($tmpl, $this->defaultTags);
+ foreach ($this->extend as $lib) {
+ $this->extendInstance[$lib] = $object = new $lib;
+ foreach ($object->tags as $name => $tag) {
+ if (!isset($this->tags[$name]) && !isset($this->defaultTags[$name])) {
+ $this->tags[$name] = $tag;
+ }
+ }
+ }
+ $tags = array_merge($this->defaultTags, $this->tags);
+ return $this->_parseTags($template, $tags);
+ }
+
+ /**
+ * 获取标签处理结果
+ * @param $name
+ * @param $tagContent
+ * @return mixed
+ */
+ private function getTagParseResult($name, $tagContent = [])
+ {
+ if (method_exists($this, $name)) {
+ return $this->{$name}($tagContent);
+ } else {
+ foreach ($this->extendInstance as $item) {
+ if (method_exists($item, $name)) {
+ return $item->{$name}($tagContent);
+ }
+ }
+ return null;
+ }
}
/**
* 进行标签处理
- * @param $tmpl
+ * @param $template
* @param $tags
* @return null|string|string[]
*/
- private function parseTags($tmpl, $tags)
+ private function _parseTags($template, $tags)
{
foreach ($tags as $name => $item) {
- $attr = ($item['attr']) ? ' +(.*?)' : null;
- $pattern = '#' . $this->left . $name . $attr . ($item['close'] ? $this->right : '\/' . $this->right . '#');
- if ($item['close']) {
- $pattern .= '([\s\S]*?)' . $this->left . '\/' . $name . $this->right . '#';
- }
- preg_match_all($pattern, $tmpl, $matches);
+ $pattern = '#' . $this->left . $name . '(.*?)' . ($item['close'] ? null : '\/') . $this->right . '#';
+ preg_match_all($pattern, $template, $matches);
for ($i = 0; $i < count($matches[0]); $i++) {
- $attrPattern = '#(.*?)=[\'"](.*?)[\'"]#';
- preg_match_all($attrPattern, $matches[1][$i], $result);
$tag = [];
- if (!empty($result)) {
- foreach ($result[1] as $key => $value) {
- $tag[trim($value, ' ')] = $result[2][$key];
+ if ($item['attr']) {
+ $attrPattern = '#(.*?)=[\'"](.*?)[\'"]#';
+ preg_match_all($attrPattern, $matches[1][$i], $result);
+ if (isset($result[0]) && !empty($result[0])) {
+ foreach ($result[1] as $key => $value) {
+ $tag[trim($value, ' ')] = $result[2][$key];
+ }
}
}
- if ($item['close']) {
- $tagContent = isset($matches[2][$i]) ? $matches[2][$i] : (($attr) ? null : $matches[1][$i]);
- $content = $this->{'_' . $name . '_start'}($tag, $tagContent);
- if ($item['close']) {
- $content .= $this->{'_' . $name . '_end'}($tag, $tagContent);
- }
- } else {
- $content = $this->{'_' . $name . '_start'}($tag);
- }
- $tmpl = str_replace($matches[0][$i], $content, $tmpl);
+ $function = ($item['close']) ? '_' . $name . '_start' : '_' . $name;
+ $template = str_replace($matches[0][$i], $this->getTagParseResult($function, $tag), $template);
+ }
+ if ($item['close']) {
+ $closePattern = '#' . $this->left . '\/' . $name . $this->right . '#';
+ $template = preg_replace_callback($closePattern, function () use ($name) {
+ $function = '_' . $name . '_end';
+ return $this->getTagParseResult($function);
+ }, $template);
}
}
- return preg_replace('#\?>([\r|\n|\s]*?)<\?php#', '', $tmpl);
+ return preg_replace('#\?>([\r|\n|\s]*?)<\?php#', '', $template);
}
/**
* 处理raw标签
- * @param $tmpl
+ * @param $template
* @return null|string|string[]
*/
- private function parseRaw($tmpl)
+ private function parseRaw($template)
{
$pattern = '#' . $this->left . 'raw' . $this->right . '([\s\S]*?)';
$pattern .= $this->left . '\/raw' . $this->right . '#';
- $tmpl = preg_replace_callback($pattern, function ($matches) {
+ $template = preg_replace_callback($pattern, function ($matches) {
return str_replace([
$this->left, $this->right,
'{', '}'
], [
'',
- '{raw!--', '--raw}'
+ '<-raw!--', '--raw->'
], $matches[1]);
- }, $tmpl);
- return $tmpl;
+ }, $template);
+ return $template;
}
/**
* 还原raw
- * @param $tmpl
- * @return null|string|string[]
+ * @param $template
+ * @return mixed
*/
- public function returnRaw($tmpl)
+ public function returnRaw($template)
{
- $pattern = '#[{|<]raw!--([\s\S]*?)--raw[>|}]#';
- $tmpl = preg_replace_callback($pattern, function ($matches) {
- $left = substr($matches[0], 0, 1);
- $right = substr($matches[0], -1);
- return $left . $matches[1] . $right;
- }, $tmpl);
- return $tmpl;
+ $template = str_replace([
+ '',
+ '<-raw!--', '--raw->'
+ ], [
+ $this->left, $this->right,
+ '{', '}'
+ ], $template);
+ return $template;
+ }
+
+ /**
+ * php标签开始
+ * @return string
+ */
+ private function _php_start()
+ {
+ return '';
}
/**
* if标签
* @param $tag
- * @param $content
* @return string
*/
- private function _if_start($tag, $content)
+ private function _if_start($tag)
{
- return '' . $content;
+ return '';
}
/**
@@ -299,10 +375,9 @@ class Engine
/**
* volist标签
* @param $tag
- * @param $content
* @return string
*/
- private function _volist_start($tag, $content)
+ private function _volist_start($tag)
{
if (substr($tag['name'], 0, 1) == ':') {
$name = substr($tag['name'], 1);
@@ -311,7 +386,7 @@ class Engine
}
$key = (empty($tag['key'])) ? null : '$' . $tag['key'] . ' = 0;';
$parse = '' . $content;
+ $parse .= ($key ? '$' . $tag['key'] . '++;' : null) . ' ?>';
return $parse;
}
@@ -329,99 +404,30 @@ class Engine
* @param $tag
* @return string
*/
- private function _assign_start($tag)
+ private function _assign($tag)
{
return '';
}
- /**
- * switch标签
- * @param $tag
- * @param $content
- * @return string
- */
- private function _switch_start($tag, $content)
- {
- $parse = '' . $content;
- return $parse;
- }
-
- /**
- * switch标签结束
- * @return string
- */
- private function _switch_end()
- {
- $parse = '';
- return $parse;
- }
-
- /**
- * case标签
- * @param $tag
- * @param $content
- * @return string
- */
- private function _case_start($tag, $content)
- {
- if (is_numeric($tag['value'])) {
- $caseVar = $tag['value'];
- } else {
- $caseVar = '\'' . $tag['value'] . '\'';
- }
- $parse = '' . $content;
- return $parse;
- }
-
- /**
- * case标签结束
- * @return string
- */
- private function _case_end()
- {
- $parse = '';
- return $parse;
- }
-
- /**
- * default标签
- * @param $tag
- * @param $content
- * @return string
- */
- private function _default_start($tag, $content)
- {
- $parse = '' . $content;
- return $parse;
- }
-
- /**
- * default标签结束
- * @return string
- */
- private function _default_end()
- {
- $parse = '';
- return $parse;
- }
-
/**
* 获取编译后的内容
- * @param $tmpl
+ * @param $template
* @return bool|mixed|null|string|string[]
*/
- public function compile($tmpl)
+ public function compile($template)
{
- $tmpl = $this->parseRaw($tmpl);
+ // 处理raw标签
+ $template = $this->parseRaw($template);
// 处理模板继承标签
- $tmpl = $this->parseExtend($tmpl);
+ $template = $this->parseExtend($template);
// 处理include标签
- $tmpl = $this->parseInclude($tmpl);
+ $template = $this->parseInclude($template);
// 处理变量以及函数
- $tmpl = $this->parseVars($tmpl);
+ $template = $this->parseVars($template);
// 处理定义的标签
- $tmpl = $this->parseDefaultTags($tmpl);
- return $tmpl;
+ $template = $this->parseTags($template);
+
+ return $template;
}
}
diff --git a/template/Extend.php b/template/Extend.php
index 77e272f..01b2a64 100644
--- a/template/Extend.php
+++ b/template/Extend.php
@@ -2,13 +2,13 @@
namespace template;
-class Extend extends Engine
+class Extend
{
- protected $tags = [
+ public $tags = [
'say' => ['attr' => 'what', 'close' => 0]
];
-
- protected function _say_start($tag)
+
+ public function _say($tag)
{
return '';
}