mirror of
https://gitee.com/fastadminnet/framework.git
synced 2026-07-08 15:42:48 +08:00
优代部分代码;block标签内可以使用{__block__}来引用所继承模板中相应block标签的内容;
模板包含文件记录及更新时间直接写入缓存的模板中;改进标签别名的处理方式,别名不再定义方法;
去除include标签传参自动生成变量的代码;cx类增加function方法,用来生成匿名函数,结合{~$函数名()}可用于递归的实现。
This commit is contained in:
@@ -52,7 +52,6 @@ class Template
|
|||||||
|
|
||||||
private $literal = [];
|
private $literal = [];
|
||||||
private $includeFile = []; // 记录所有模板包含的文件路径及更新时间
|
private $includeFile = []; // 记录所有模板包含的文件路径及更新时间
|
||||||
private $md5Key = ''; // 保存当前模板的md5码
|
|
||||||
protected $storage = null;
|
protected $storage = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -118,7 +117,7 @@ class Template
|
|||||||
/**
|
/**
|
||||||
* 模板引擎配置项
|
* 模板引擎配置项
|
||||||
* @access public
|
* @access public
|
||||||
* @param array $config
|
* @param array|string $config
|
||||||
* @return void|array
|
* @return void|array
|
||||||
*/
|
*/
|
||||||
public function config($config)
|
public function config($config)
|
||||||
@@ -146,7 +145,7 @@ class Template
|
|||||||
if (isset($data[$val])) {
|
if (isset($data[$val])) {
|
||||||
$data = $data[$val];
|
$data = $data[$val];
|
||||||
} else {
|
} else {
|
||||||
$data = false;
|
$data = null;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -172,7 +171,7 @@ class Template
|
|||||||
}
|
}
|
||||||
$template = $this->parseTemplateFile($template);
|
$template = $this->parseTemplateFile($template);
|
||||||
$cacheFile = $this->config['cache_path'] . $this->config['cache_prefix'] . md5($template) . $this->config['cache_suffix'];
|
$cacheFile = $this->config['cache_path'] . $this->config['cache_prefix'] . md5($template) . $this->config['cache_suffix'];
|
||||||
if (!$this->checkCache($template, $cacheFile)) {
|
if (!$this->checkCache($cacheFile)) {
|
||||||
// 缓存无效 重新模板编译
|
// 缓存无效 重新模板编译
|
||||||
$content = file_get_contents($template);
|
$content = file_get_contents($template);
|
||||||
$this->compiler($content, $cacheFile);
|
$this->compiler($content, $cacheFile);
|
||||||
@@ -204,7 +203,7 @@ class Template
|
|||||||
$this->data = $vars;
|
$this->data = $vars;
|
||||||
}
|
}
|
||||||
$cacheFile = $this->config['cache_path'] . $this->config['cache_prefix'] . md5($content) . $this->config['cache_suffix'];
|
$cacheFile = $this->config['cache_path'] . $this->config['cache_prefix'] . md5($content) . $this->config['cache_suffix'];
|
||||||
if (!$this->checkCache($content, $cacheFile)) {
|
if (!$this->checkCache($cacheFile)) {
|
||||||
// 缓存无效 模板编译
|
// 缓存无效 模板编译
|
||||||
$this->compiler($content, $cacheFile);
|
$this->compiler($content, $cacheFile);
|
||||||
}
|
}
|
||||||
@@ -235,30 +234,27 @@ class Template
|
|||||||
* 检查编译缓存是否有效
|
* 检查编译缓存是否有效
|
||||||
* 如果无效则需要重新编译
|
* 如果无效则需要重新编译
|
||||||
* @access private
|
* @access private
|
||||||
* @param string $template 模板文件名
|
|
||||||
* @param string $cacheFile 缓存文件名
|
* @param string $cacheFile 缓存文件名
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
private function checkCache($template, $cacheFile)
|
private function checkCache($cacheFile)
|
||||||
{
|
{
|
||||||
if (!$this->config['tpl_cache']) {
|
if (!$this->config['tpl_cache']) {
|
||||||
// 优先对配置设定检测
|
// 优先对配置设定检测
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
$this->md5Key = md5($template);
|
if (is_file($cacheFile)) {
|
||||||
$recordFile = $this->config['cache_path'] . md5($this->config['cache_record_file']) . $this->config['cache_suffix'];
|
$handle = @fopen($cacheFile, "r");
|
||||||
if (!is_file($recordFile)) {
|
if ($handle) {
|
||||||
return false;
|
preg_match('/\/\*(.+?)\*\//', fgets($handle), $matches);
|
||||||
} else {
|
if (isset($matches[1])) {
|
||||||
$this->includeFile = $this->storage->read($recordFile, [], true);
|
$this->includeFile = unserialize($matches[1]);
|
||||||
if (!isset($this->includeFile[$this->md5Key])) {
|
// 检查编译存储是否有效
|
||||||
// 缓存记录中无此模板
|
return $this->storage->check($this->includeFile, $cacheFile, $this->config['cache_time']);
|
||||||
return false;
|
}
|
||||||
} else {
|
|
||||||
// 检查编译存储是否有效
|
|
||||||
return $this->storage->check($this->includeFile[$this->md5Key], $cacheFile, $this->config['cache_time']);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -298,7 +294,7 @@ class Template
|
|||||||
// 替换布局的主体内容
|
// 替换布局的主体内容
|
||||||
$content = str_replace($this->config['layout_item'], $content, file_get_contents($layoutFile));
|
$content = str_replace($this->config['layout_item'], $content, file_get_contents($layoutFile));
|
||||||
// 记录布局文件的更新时间
|
// 记录布局文件的更新时间
|
||||||
$this->includeFile[$this->md5Key][filemtime($layoutFile)] = $layoutFile;
|
$this->includeFile[filemtime($layoutFile)] = $layoutFile;
|
||||||
} else {
|
} else {
|
||||||
throw new Exception('template not exist:' . $layoutFile, 10700);
|
throw new Exception('template not exist:' . $layoutFile, 10700);
|
||||||
}
|
}
|
||||||
@@ -307,8 +303,6 @@ class Template
|
|||||||
|
|
||||||
// 模板解析
|
// 模板解析
|
||||||
$this->parse($content);
|
$this->parse($content);
|
||||||
// 添加安全代码
|
|
||||||
$content = '<?php if (!defined(\'THINK_PATH\')) exit();?>' . $content;
|
|
||||||
if ($this->config['strip_space']) {
|
if ($this->config['strip_space']) {
|
||||||
/* 去除html空格与换行 */
|
/* 去除html空格与换行 */
|
||||||
$find = ['~>\s+<~', '~>(\s+\n|\r)~'];
|
$find = ['~>\s+<~', '~>(\s+\n|\r)~'];
|
||||||
@@ -320,11 +314,10 @@ class Template
|
|||||||
// 模板过滤输出
|
// 模板过滤输出
|
||||||
$replace = $this->config['tpl_replace_string'];
|
$replace = $this->config['tpl_replace_string'];
|
||||||
$content = str_replace(array_keys($replace), array_values($replace), $content);
|
$content = str_replace(array_keys($replace), array_values($replace), $content);
|
||||||
|
// 添加安全代码及模板引用记录
|
||||||
|
$content = '<?php if (!defined(\'THINK_PATH\')) exit(); /*' . serialize($this->includeFile) . '*/ ?>' . "\n" . $content;
|
||||||
// 编译存储
|
// 编译存储
|
||||||
$this->storage->write($cacheFile, $content);
|
$this->storage->write($cacheFile, $content);
|
||||||
// 保存模板更新记录
|
|
||||||
$string = "<?php\nreturn " . var_export($this->includeFile, true) . ';';
|
|
||||||
$this->storage->write($this->config['cache_path'] . md5($this->config['cache_record_file']) . $this->config['cache_suffix'], $string);
|
|
||||||
$this->includeFile = [];
|
$this->includeFile = [];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -429,7 +422,7 @@ class Template
|
|||||||
// 替换布局的主体内容
|
// 替换布局的主体内容
|
||||||
$content = str_replace($replace, $content, file_get_contents($layoutFile));
|
$content = str_replace($replace, $content, file_get_contents($layoutFile));
|
||||||
// 记录布局文件的更新时间
|
// 记录布局文件的更新时间
|
||||||
$this->includeFile[$this->md5Key][filemtime($layoutFile)] = $layoutFile;
|
$this->includeFile[filemtime($layoutFile)] = $layoutFile;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -446,8 +439,8 @@ class Template
|
|||||||
*/
|
*/
|
||||||
private function parseInclude(&$content)
|
private function parseInclude(&$content)
|
||||||
{
|
{
|
||||||
$regex = $this->getRegex('include');
|
$regex = $this->getRegex('include');
|
||||||
$funReplace = function ($template) use (&$funReplace, &$regex, &$content) {
|
$func = function ($template) use (&$func, &$regex, &$content) {
|
||||||
if (preg_match_all($regex, $template, $matches, PREG_SET_ORDER)) {
|
if (preg_match_all($regex, $template, $matches, PREG_SET_ORDER)) {
|
||||||
foreach ($matches as $match) {
|
foreach ($matches as $match) {
|
||||||
$array = $this->parseAttr($match[0]);
|
$array = $this->parseAttr($match[0]);
|
||||||
@@ -455,28 +448,22 @@ class Template
|
|||||||
unset($array['file']);
|
unset($array['file']);
|
||||||
// 分析模板文件名并读取内容
|
// 分析模板文件名并读取内容
|
||||||
$parseStr = $this->parseTemplateName($file);
|
$parseStr = $this->parseTemplateName($file);
|
||||||
// 替换变量
|
|
||||||
$varStr = "";
|
|
||||||
foreach ($array as $k => $v) {
|
foreach ($array as $k => $v) {
|
||||||
// 以$开头字符串转换成模板变量
|
// 以$开头字符串转换成模板变量
|
||||||
if (0 === strpos($v, '$')) {
|
if (0 === strpos($v, '$')) {
|
||||||
$v = $this->get(substr($v, 1));
|
$v = $this->get(substr($v, 1));
|
||||||
}
|
}
|
||||||
// 兼容 [var_name] 静态渲染
|
|
||||||
$parseStr = str_replace('[' . $k . ']', $v, $parseStr);
|
$parseStr = str_replace('[' . $k . ']', $v, $parseStr);
|
||||||
// 支持 $var_name = value 动态赋值
|
|
||||||
$varStr .= "{assign name=\"{$k}\" value=\"{$v}\" /}";
|
|
||||||
}
|
}
|
||||||
$parseStr = $varStr . $parseStr;
|
|
||||||
$content = str_replace($match[0], $parseStr, $content);
|
$content = str_replace($match[0], $parseStr, $content);
|
||||||
// 再次对包含文件进行模板分析
|
// 再次对包含文件进行模板分析
|
||||||
$funReplace($parseStr);
|
$func($parseStr);
|
||||||
}
|
}
|
||||||
unset($matches);
|
unset($matches);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// 替换模板中的include标签
|
// 替换模板中的include标签
|
||||||
$funReplace($content);
|
$func($content);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -489,23 +476,23 @@ class Template
|
|||||||
private function parseExtend(&$content)
|
private function parseExtend(&$content)
|
||||||
{
|
{
|
||||||
$regex = $this->getRegex('extend');
|
$regex = $this->getRegex('extend');
|
||||||
$array = $blocks = $extBlocks = [];
|
$array = $blocks = $baseBlocks = [];
|
||||||
$extend = '';
|
$extend = '';
|
||||||
$fun = function ($template) use (&$fun, &$regex, &$array, &$extend, &$blocks, &$extBlocks) {
|
$func = function ($template) use (&$func, &$regex, &$array, &$extend, &$blocks, &$baseBlocks) {
|
||||||
if (preg_match($regex, $template, $matches)) {
|
if (preg_match($regex, $template, $matches)) {
|
||||||
if (!isset($array[$matches['name']])) {
|
if (!isset($array[$matches['name']])) {
|
||||||
$array[$matches['name']] = 1;
|
$array[$matches['name']] = 1;
|
||||||
// 读取继承模板
|
// 读取继承模板
|
||||||
$extend = $this->parseTemplateName($matches['name']);
|
$extend = $this->parseTemplateName($matches['name']);
|
||||||
// 递归检查继承
|
// 递归检查继承
|
||||||
$fun($extend);
|
$func($extend);
|
||||||
// 取得block标签内容
|
// 取得block标签内容
|
||||||
$blocks = array_merge($blocks, $this->parseBlock($template));
|
$blocks = array_merge($blocks, $this->parseBlock($template));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 取得顶层模板block标签内容
|
// 取得顶层模板block标签内容
|
||||||
$extBlocks = $this->parseBlock($template);
|
$baseBlocks = $this->parseBlock($template, true);
|
||||||
if (empty($extend)) {
|
if (empty($extend)) {
|
||||||
// 无extend标签但有block标签的情况
|
// 无extend标签但有block标签的情况
|
||||||
$extend = $template;
|
$extend = $template;
|
||||||
@@ -513,15 +500,36 @@ class Template
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
$fun($content);
|
$func($content);
|
||||||
if (!empty($extend)) {
|
if (!empty($extend)) {
|
||||||
if ($extBlocks) {
|
if ($baseBlocks) {
|
||||||
foreach ($extBlocks as $name => $v) {
|
$children = [];
|
||||||
$replace = isset($blocks[$name]) ? $blocks[$name]['content'] : $v['content'];
|
foreach ($baseBlocks as $name => $val) {
|
||||||
$extend = str_replace($v['begin']['tag'] . $v['content'] . $v['end']['tag'], $replace, $extend);
|
$replace = $val['content'];
|
||||||
|
if (!empty($children[$name])) {
|
||||||
|
// 如果包含有子block标签
|
||||||
|
foreach ($children[$name] as $key) {
|
||||||
|
$replace = str_replace($baseBlocks[$key]['begin'] . $baseBlocks[$key]['content'] . $baseBlocks[$key]['end'], $blocks[$key]['content'], $replace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 带有{__block__}表示与所继承模板的相应标签合并,而不是覆盖
|
||||||
|
$replace = !isset($blocks[$name]) ? $replace : str_replace(['{__BLOCK__}', '{__block__}'], $replace, $blocks[$name]['content']);
|
||||||
|
if (!empty($val['parent'])) {
|
||||||
|
// 如果不是最顶层的block标签
|
||||||
|
$parent = $val['parent'];
|
||||||
|
if (isset($blocks[$parent])) {
|
||||||
|
$blocks[$parent]['content'] = str_replace($blocks[$name]['begin'] . $blocks[$name]['content'] . $blocks[$name]['end'], $replace, $blocks[$parent]['content']);
|
||||||
|
}
|
||||||
|
$blocks[$name]['content'] = $replace;
|
||||||
|
$children[$parent][] = $name;
|
||||||
|
} else {
|
||||||
|
// 替换模板中的block标签
|
||||||
|
$extend = str_replace($val['begin'] . $val['content'] . $val['end'], $replace, $extend);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$content = $extend;
|
$content = $extend;
|
||||||
|
unset($blocks, $baseBlocks);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -540,18 +548,18 @@ class Template
|
|||||||
if (!$restore) {
|
if (!$restore) {
|
||||||
$count = count($this->literal);
|
$count = count($this->literal);
|
||||||
// 替换literal标签
|
// 替换literal标签
|
||||||
foreach ($matches as $i => $match) {
|
foreach ($matches as $match) {
|
||||||
$this->literal[] = substr($match[0], strlen($match[1]), -strlen($match[2]));
|
$this->literal[] = substr($match[0], strlen($match[1]), -strlen($match[2]));
|
||||||
$content = str_replace($match[0], "<!--###literal{$count}###-->", $content);
|
$content = str_replace($match[0], "<!--###literal{$count}###-->", $content);
|
||||||
$count++;
|
$count++;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 还原literal标签
|
// 还原literal标签
|
||||||
foreach ($matches as $i => $match) {
|
foreach ($matches as $match) {
|
||||||
$content = str_replace($match[0], $this->literal[$i], $content);
|
$content = str_replace($match[0], $this->literal[$match[1]], $content);
|
||||||
}
|
}
|
||||||
// 销毁literal记录
|
// 清空literal记录
|
||||||
unset($this->literal);
|
$this->literal = [];
|
||||||
}
|
}
|
||||||
unset($matches);
|
unset($matches);
|
||||||
}
|
}
|
||||||
@@ -562,31 +570,31 @@ class Template
|
|||||||
* 获取模板中的block标签
|
* 获取模板中的block标签
|
||||||
* @access private
|
* @access private
|
||||||
* @param string $content 模板内容
|
* @param string $content 模板内容
|
||||||
|
* @param boolean $sort 是否排序
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
private function parseBlock(&$content)
|
private function parseBlock(&$content, $sort = false)
|
||||||
{
|
{
|
||||||
$regex = $this->getRegex('block');
|
$regex = $this->getRegex('block');
|
||||||
$array = [];
|
$result = [];
|
||||||
if (preg_match_all($regex, $content, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)) {
|
if (preg_match_all($regex, $content, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)) {
|
||||||
$right = $keys = [];
|
$right = $keys = [];
|
||||||
foreach ($matches as $match) {
|
foreach ($matches as $match) {
|
||||||
if (empty($match['name'][0])) {
|
if (empty($match['name'][0])) {
|
||||||
if (!empty($right)) {
|
if (count($right) > 0) {
|
||||||
$begin = array_pop($right);
|
$tag = array_pop($right);
|
||||||
$end = ['offset' => $match[0][1], 'tag' => $match[0][0]];
|
$start = $tag['offset'] + strlen($tag['tag']);
|
||||||
$start = $begin['offset'] + strlen($begin['tag']);
|
$length = $match[0][1] - $start;
|
||||||
$len = $end['offset'] - $start;
|
$result[$tag['name']] = [
|
||||||
$array[$begin['name']] = [
|
'begin' => $tag['tag'],
|
||||||
'begin' => $begin,
|
'content' => substr($content, $start, $length),
|
||||||
'content' => substr($content, $start, $len),
|
'end' => $match[0][0],
|
||||||
'end' => $end,
|
'parent' => count($right) ? end($right)['name'] : '',
|
||||||
];
|
];
|
||||||
$keys[] = $begin['offset'];
|
$keys[$tag['name']] = $match[0][1];
|
||||||
} else {
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// 标签头压入栈
|
||||||
$right[] = [
|
$right[] = [
|
||||||
'name' => $match[2][0],
|
'name' => $match[2][0],
|
||||||
'offset' => $match[0][1],
|
'offset' => $match[0][1],
|
||||||
@@ -595,10 +603,12 @@ class Template
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
unset($right, $matches);
|
unset($right, $matches);
|
||||||
// 按blocks标签在模板中的位置排序
|
if ($sort) {
|
||||||
array_multisort($keys, $array);
|
// 按block标签结束符在模板中的位置排序
|
||||||
|
array_multisort($keys, $result);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return $array;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -703,37 +713,37 @@ class Template
|
|||||||
} elseif (')' == substr($name, -1, 1)) {
|
} elseif (')' == substr($name, -1, 1)) {
|
||||||
// $name为对象或是自动识别,或者含有函数
|
// $name为对象或是自动识别,或者含有函数
|
||||||
switch ($first) {
|
switch ($first) {
|
||||||
case '?':
|
case '?':
|
||||||
$str = '<?php echo ' . $name . ' ? ' . $name . ' : ' . substr($str, 1) . '; ?>';
|
$str = '<?php echo ' . $name . ' ? ' . $name . ' : ' . substr($str, 1) . '; ?>';
|
||||||
break;
|
break;
|
||||||
case '=':
|
case '=':
|
||||||
$str = '<?php if(' . $name . ') echo ' . substr($str, 1) . '; ?>';
|
$str = '<?php if(' . $name . ') echo ' . substr($str, 1) . '; ?>';
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
$str = '<?php echo ' . $name . '?' . $str . '; ?>';
|
$str = '<?php echo ' . $name . '?' . $str . '; ?>';
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// $name为数组
|
// $name为数组
|
||||||
switch ($first) {
|
switch ($first) {
|
||||||
case '?':
|
case '?':
|
||||||
// {$varname??'xxx'} $varname有定义则输出$varname,否则输出xxx
|
// {$varname??'xxx'} $varname有定义则输出$varname,否则输出xxx
|
||||||
$str = '<?php echo isset(' . $name . ') ? ' . $name . ' : ' . substr($str, 1) . '; ?>';
|
$str = '<?php echo isset(' . $name . ') ? ' . $name . ' : ' . substr($str, 1) . '; ?>';
|
||||||
break;
|
break;
|
||||||
case '=':
|
case '=':
|
||||||
// {$varname?='xxx'} $varname为真时才输出xxx
|
// {$varname?='xxx'} $varname为真时才输出xxx
|
||||||
$str = '<?php if(!empty(' . $name . ')) echo ' . substr($str, 1) . '; ?>';
|
$str = '<?php if(!empty(' . $name . ')) echo ' . substr($str, 1) . '; ?>';
|
||||||
break;
|
break;
|
||||||
case ':':
|
case ':':
|
||||||
// {$varname?:'xxx'} $varname为真时输出$varname,否则输出xxx
|
// {$varname?:'xxx'} $varname为真时输出$varname,否则输出xxx
|
||||||
$str = '<?php echo !empty(' . $name . ')?' . $name . $str . '; ?>';
|
$str = '<?php echo !empty(' . $name . ')?' . $name . $str . '; ?>';
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (strpos($str, ':')) {
|
if (strpos($str, ':')) {
|
||||||
// {$varname ? 'a' : 'b'} $varname为真时输出a,否则输出b
|
// {$varname ? 'a' : 'b'} $varname为真时输出a,否则输出b
|
||||||
$str = '<?php echo !empty(' . $name . ')?' . $str . '; ?>';
|
$str = '<?php echo !empty(' . $name . ')?' . $str . '; ?>';
|
||||||
} else {
|
} else {
|
||||||
$str = '<?php echo ' . $name . '?' . $str . '; ?>';
|
$str = '<?php echo ' . $name . '?' . $str . '; ?>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -836,9 +846,10 @@ class Template
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
static $_varFunctionList = [];
|
static $_varFunctionList = [];
|
||||||
|
$_key = md5($varStr);
|
||||||
//如果已经解析过该变量字串,则直接返回变量值
|
//如果已经解析过该变量字串,则直接返回变量值
|
||||||
if (isset($_varFunctionList[$varStr])) {
|
if (isset($_varFunctionList[$_key])) {
|
||||||
$varStr = $_varFunctionList[$varStr];
|
$varStr = $_varFunctionList[$_key];
|
||||||
} else {
|
} else {
|
||||||
$varArray = explode('|', $varStr);
|
$varArray = explode('|', $varStr);
|
||||||
// 取得变量名称
|
// 取得变量名称
|
||||||
@@ -876,6 +887,7 @@ class Template
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
$_varFunctionList[$_key] = $name;
|
||||||
$varStr = $name;
|
$varStr = $name;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@@ -988,7 +1000,7 @@ class Template
|
|||||||
// 获取模板文件内容
|
// 获取模板文件内容
|
||||||
$parseStr .= file_get_contents($template);
|
$parseStr .= file_get_contents($template);
|
||||||
// 记录模板文件的更新时间
|
// 记录模板文件的更新时间
|
||||||
$this->includeFile[$this->md5Key][filemtime($template)] = $template;
|
$this->includeFile[filemtime($template)] = $template;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $parseStr;
|
return $parseStr;
|
||||||
@@ -1019,55 +1031,56 @@ class Template
|
|||||||
*/
|
*/
|
||||||
private function getRegex($tagName)
|
private function getRegex($tagName)
|
||||||
{
|
{
|
||||||
$begin = $this->config['taglib_begin'];
|
|
||||||
$end = $this->config['taglib_end'];
|
|
||||||
$single = strlen(ltrim($begin, '\\')) == 1 && strlen(ltrim($end, '\\')) == 1 ? true : false;
|
|
||||||
$regex = '';
|
$regex = '';
|
||||||
switch ($tagName) {
|
if ('tag' == $tagName) {
|
||||||
case 'block':
|
$begin = $this->config['tpl_begin'];
|
||||||
if ($single) {
|
$end = $this->config['tpl_end'];
|
||||||
$regex = $begin . '(?:' . $tagName . '\b(?>(?:(?!name=).)*)\bname=([\'\"])(?<name>[\w\/\:@,]+)\\1(?>[^' . $end . ']*)|\/' . $tagName . ')' . $end;
|
if (strlen(ltrim($begin, '\\')) == 1 && strlen(ltrim($end, '\\')) == 1) {
|
||||||
} else {
|
$regex = $begin . '((?:[\$]{1,2}[a-wA-w_]|[\:\~][\$a-wA-w_]|[+]{2}[\$][a-wA-w_]|[-]{2}[\$][a-wA-w_]|\/[\*\/])(?>[^' . $end . ']*))' . $end;
|
||||||
$regex = $begin . '(?:' . $tagName . '\b(?>(?:(?!name=).)*)\bname=([\'\"])(?<name>[\w\/\:@,]+)\\1(?>(?:(?!' . $end . ').)*)|\/' . $tagName . ')' . $end;
|
} else {
|
||||||
}
|
$regex = $begin . '((?:[\$]{1,2}[a-wA-w_]|[\:\~][\$a-wA-w_]|[+]{2}[\$][a-wA-w_]|[-]{2}[\$][a-wA-w_]|\/[\*\/])(?>(?:(?!' . $end . ').)*))' . $end;
|
||||||
break;
|
}
|
||||||
case 'literal':
|
} else {
|
||||||
if ($single) {
|
$begin = $this->config['taglib_begin'];
|
||||||
$regex = '(' . $begin . $tagName . '\b(?>[^' . $end . ']*)' . $end . ')';
|
$end = $this->config['taglib_end'];
|
||||||
$regex .= '(?:(?>[^' . $begin . ']*)(?>(?!' . $begin . '(?>' . $tagName . '\b[^' . $end . ']*|\/' . $tagName . ')' . $end . ')' . $begin . '[^' . $begin . ']*)*)';
|
$single = strlen(ltrim($begin, '\\')) == 1 && strlen(ltrim($end, '\\')) == 1 ? true : false;
|
||||||
$regex .= '(' . $begin . '\/' . $tagName . $end . ')';
|
switch ($tagName) {
|
||||||
} else {
|
case 'block':
|
||||||
$regex = '(' . $begin . $tagName . '\b(?>(?:(?!' . $end . ').)*)' . $end . ')';
|
if ($single) {
|
||||||
$regex .= '(?:(?>(?:(?!' . $begin . ').)*)(?>(?!' . $begin . '(?>' . $tagName . '\b(?>(?:(?!' . $end . ').)*)|\/' . $tagName . ')' . $end . ')' . $begin . '(?>(?:(?!' . $begin . ').)*))*)';
|
$regex = $begin . '(?:' . $tagName . '\b(?>(?:(?!name=).)*)\bname=([\'\"])(?<name>[\$\w\-\/\.]+)\\1(?>[^' . $end . ']*)|\/' . $tagName . ')' . $end;
|
||||||
$regex .= '(' . $begin . '\/' . $tagName . $end . ')';
|
} else {
|
||||||
}
|
$regex = $begin . '(?:' . $tagName . '\b(?>(?:(?!name=).)*)\bname=([\'\"])(?<name>[\$\w\-\/\.]+)\\1(?>(?:(?!' . $end . ').)*)|\/' . $tagName . ')' . $end;
|
||||||
break;
|
}
|
||||||
case 'restoreliteral':
|
break;
|
||||||
$regex = '<!--###literal(\d+)###-->';
|
case 'literal':
|
||||||
break;
|
if ($single) {
|
||||||
case 'include':
|
$regex = '(' . $begin . $tagName . '\b(?>[^' . $end . ']*)' . $end . ')';
|
||||||
$name = 'file';
|
$regex .= '(?:(?>[^' . $begin . ']*)(?>(?!' . $begin . '(?>' . $tagName . '\b[^' . $end . ']*|\/' . $tagName . ')' . $end . ')' . $begin . '[^' . $begin . ']*)*)';
|
||||||
case 'taglib':
|
$regex .= '(' . $begin . '\/' . $tagName . $end . ')';
|
||||||
case 'layout':
|
} else {
|
||||||
case 'extend':
|
$regex = '(' . $begin . $tagName . '\b(?>(?:(?!' . $end . ').)*)' . $end . ')';
|
||||||
if (empty($name)) {
|
$regex .= '(?:(?>(?:(?!' . $begin . ').)*)(?>(?!' . $begin . '(?>' . $tagName . '\b(?>(?:(?!' . $end . ').)*)|\/' . $tagName . ')' . $end . ')' . $begin . '(?>(?:(?!' . $begin . ').)*))*)';
|
||||||
$name = 'name';
|
$regex .= '(' . $begin . '\/' . $tagName . $end . ')';
|
||||||
}
|
}
|
||||||
if ($single) {
|
break;
|
||||||
$regex = $begin . $tagName . '\b(?>(?:(?!' . $name . '=).)*)\b' . $name . '=([\'\"])(?<name>[\$\w\-\/\.\:@,\\\\]+)\\1(?>[^' . $end . ']*)' . $end;
|
case 'restoreliteral':
|
||||||
} else {
|
$regex = '<!--###literal(\d+)###-->';
|
||||||
$regex = $begin . $tagName . '\b(?>(?:(?!' . $name . '=).)*)\b' . $name . '=([\'\"])(?<name>[\$\w\-\/\.\:@,\\\\]+)\\1(?>(?:(?!' . $end . ').)*)' . $end;
|
break;
|
||||||
}
|
case 'include':
|
||||||
break;
|
$name = 'file';
|
||||||
case 'tag':
|
case 'taglib':
|
||||||
$begin = $this->config['tpl_begin'];
|
case 'layout':
|
||||||
$end = $this->config['tpl_end'];
|
case 'extend':
|
||||||
if (strlen(ltrim($begin, '\\')) == 1 && strlen(ltrim($end, '\\')) == 1) {
|
if (empty($name)) {
|
||||||
$regex = $begin . '((?:[\$]{1,2}[a-wA-w_]|[\:\~][\$a-wA-w_]|[+]{2}[\$][a-wA-w_]|[-]{2}[\$][a-wA-w_]|\/[\*\/])(?>[^' . $end . ']*))' . $end;
|
$name = 'name';
|
||||||
} else {
|
}
|
||||||
$regex = $begin . '((?:[\$]{1,2}[a-wA-w_]|[\:\~][\$a-wA-w_]|[+]{2}[\$][a-wA-w_]|[-]{2}[\$][a-wA-w_]|\/[\*\/])(?>(?:(?!' . $end . ').)*))' . $end;
|
if ($single) {
|
||||||
}
|
$regex = $begin . $tagName . '\b(?>(?:(?!' . $name . '=).)*)\b' . $name . '=([\'\"])(?<name>[\$\w\-\/\.\:@,\\\\]+)\\1(?>[^' . $end . ']*)' . $end;
|
||||||
break;
|
} else {
|
||||||
|
$regex = $begin . $tagName . '\b(?>(?:(?!' . $name . '=).)*)\b' . $name . '=([\'\"])(?<name>[\$\w\-\/\.\:@,\\\\]+)\\1(?>(?:(?!' . $end . ').)*)' . $end;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return '/' . $regex . '/is';
|
return '/' . $regex . '/is';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,15 +87,15 @@ class TagLib
|
|||||||
public function parseTag(&$content, $lib = '')
|
public function parseTag(&$content, $lib = '')
|
||||||
{
|
{
|
||||||
$tags = [];
|
$tags = [];
|
||||||
|
$_lib = $lib ? $lib . ':' : '';
|
||||||
foreach ($this->tags as $name => $val) {
|
foreach ($this->tags as $name => $val) {
|
||||||
$close = !isset($val['close']) || $val['close'] ? 1 : 0;
|
$close = !isset($val['close']) || $val['close'] ? 1 : 0;
|
||||||
$_key = $lib ? $lib . ':' . $name : $name;
|
$tags[$close][$_lib . $name] = $name;
|
||||||
$tags[$close][$_key] = $name;
|
|
||||||
if (isset($val['alias'])) {
|
if (isset($val['alias'])) {
|
||||||
// 别名设置
|
// 别名设置
|
||||||
foreach (explode(',', $val['alias']) as $v) {
|
$array = (array) $val['alias'];
|
||||||
$_key = $lib ? $lib . ':' . $v : $v;
|
foreach (explode(',', $array[0]) as $v) {
|
||||||
$tags[$close][$_key] = $v;
|
$tags[$close][$_lib . $v] = $name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -117,8 +117,6 @@ class TagLib
|
|||||||
'begin' => array_pop($right[$name]), // 标签开始符
|
'begin' => array_pop($right[$name]), // 标签开始符
|
||||||
'end' => $match[0], // 标签结束符
|
'end' => $match[0], // 标签结束符
|
||||||
];
|
];
|
||||||
} else {
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 标签头压入栈
|
// 标签头压入栈
|
||||||
@@ -136,9 +134,10 @@ class TagLib
|
|||||||
// 标签替换 从后向前
|
// 标签替换 从后向前
|
||||||
foreach ($nodes as $pos => $node) {
|
foreach ($nodes as $pos => $node) {
|
||||||
// 对应的标签名
|
// 对应的标签名
|
||||||
$name = $tags[1][$node['name']];
|
$name = $tags[1][$node['name']];
|
||||||
|
$alias = $_lib . $name != $node['name'] ? ($_lib ? strstr($node['name'], $_lib) : $node['name']) : '';
|
||||||
// 解析标签属性
|
// 解析标签属性
|
||||||
$attrs = $this->parseAttr($node['begin'][0], $name);
|
$attrs = $this->parseAttr($node['begin'][0], $name, $alias);
|
||||||
$method = '_' . $name;
|
$method = '_' . $name;
|
||||||
// 读取标签库中对应的标签内容 replace[0]用来替换标签头,replace[1]用来替换标签尾
|
// 读取标签库中对应的标签内容 replace[0]用来替换标签头,replace[1]用来替换标签尾
|
||||||
$replace = explode($break, $this->$method($attrs, $break));
|
$replace = explode($break, $this->$method($attrs, $break));
|
||||||
@@ -171,11 +170,12 @@ class TagLib
|
|||||||
// 自闭合标签
|
// 自闭合标签
|
||||||
if (!empty($tags[0])) {
|
if (!empty($tags[0])) {
|
||||||
$regex = $this->getRegex(array_keys($tags[0]), 0);
|
$regex = $this->getRegex(array_keys($tags[0]), 0);
|
||||||
$content = preg_replace_callback($regex, function ($matches) use (&$tags) {
|
$content = preg_replace_callback($regex, function ($matches) use (&$tags, &$_lib) {
|
||||||
// 对应的标签名
|
// 对应的标签名
|
||||||
$name = $tags[0][$matches[1]];
|
$name = $tags[0][$matches[1]];
|
||||||
|
$alias = $_lib . $name != $matches[1] ? ($_lib ? strstr($matches[1], $_lib) : $matches[1]) : '';
|
||||||
// 解析标签属性
|
// 解析标签属性
|
||||||
$attrs = $this->parseAttr($matches[0], $name);
|
$attrs = $this->parseAttr($matches[0], $name, $alias);
|
||||||
$method = '_' . $name;
|
$method = '_' . $name;
|
||||||
return $this->$method($attrs, '');
|
return $this->$method($attrs, '');
|
||||||
}, $content);
|
}, $content);
|
||||||
@@ -192,14 +192,10 @@ class TagLib
|
|||||||
*/
|
*/
|
||||||
private function getRegex($tags, $close)
|
private function getRegex($tags, $close)
|
||||||
{
|
{
|
||||||
$begin = $this->tpl->config('taglib_begin');
|
$begin = $this->tpl->config('taglib_begin');
|
||||||
$end = $this->tpl->config('taglib_end');
|
$end = $this->tpl->config('taglib_end');
|
||||||
$single = strlen(ltrim($begin, '\\')) == 1 && strlen(ltrim($end, '\\')) == 1 ? true : false;
|
$single = strlen(ltrim($begin, '\\')) == 1 && strlen(ltrim($end, '\\')) == 1 ? true : false;
|
||||||
if (is_array($tags)) {
|
$tagName = is_array($tags) ? implode('|', $tags) : $tags;
|
||||||
$tagName = implode('|', $tags);
|
|
||||||
} else {
|
|
||||||
$tagName = $tags;
|
|
||||||
}
|
|
||||||
if ($single) {
|
if ($single) {
|
||||||
if ($close) {
|
if ($close) {
|
||||||
// 如果是闭合标签
|
// 如果是闭合标签
|
||||||
@@ -218,98 +214,45 @@ class TagLib
|
|||||||
return '/' . $regex . '/is';
|
return '/' . $regex . '/is';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* TagLib标签属性分析 返回标签属性数组
|
|
||||||
* @access public
|
|
||||||
* @param string $attr 标签属性字符串
|
|
||||||
* @param string $tag 标签名
|
|
||||||
* @return array
|
|
||||||
* @throws Exception
|
|
||||||
* @internal param string $tagStr 标签内容
|
|
||||||
*/
|
|
||||||
public function parseXmlAttr($attr, $tag)
|
|
||||||
{
|
|
||||||
if ('' == trim($attr)) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
//XML解析安全过滤
|
|
||||||
$attr = str_replace('&', '___', $attr);
|
|
||||||
if (substr($attr, 0, 1) == '<' && substr($attr, -1, 1) == '>') {
|
|
||||||
$xml = '<tpl>' . $attr . '</tpl>';
|
|
||||||
} else {
|
|
||||||
$xml = '<tpl><tag ' . $attr . ' /></tpl>';
|
|
||||||
}
|
|
||||||
$xml = simplexml_load_string($xml);
|
|
||||||
if (!$xml) {
|
|
||||||
throw new Exception('_XML_TAG_ERROR_ : ' . $attr);
|
|
||||||
}
|
|
||||||
$xml = (array) ($xml->tag->attributes());
|
|
||||||
if (isset($xml['@attributes']) && $result = array_change_key_case($xml['@attributes'])) {
|
|
||||||
$tag = strtolower($tag);
|
|
||||||
if (!isset($this->tags[$tag])) {
|
|
||||||
// 检测是否存在别名定义
|
|
||||||
foreach ($this->tags as $key => $val) {
|
|
||||||
if (isset($val['alias']) && in_array($tag, explode(',', $val['alias']))) {
|
|
||||||
$item = $val;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$item = $this->tags[$tag];
|
|
||||||
}
|
|
||||||
if (!empty($item['attr'])) {
|
|
||||||
if (isset($item['must'])) {
|
|
||||||
$must = explode(',', $item['must']);
|
|
||||||
} else {
|
|
||||||
$must = [];
|
|
||||||
}
|
|
||||||
$attrs = explode(',', $item['attr']);
|
|
||||||
foreach ($attrs as $name) {
|
|
||||||
if (isset($result[$name])) {
|
|
||||||
$result[$name] = str_replace('___', '&', $result[$name]);
|
|
||||||
} elseif (false !== array_search($name, $must)) {
|
|
||||||
throw new Exception('_PARAM_ERROR_:' . $name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $result;
|
|
||||||
} else {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 分析标签属性 正则方式
|
* 分析标签属性 正则方式
|
||||||
* @access public
|
* @access public
|
||||||
* @param string $str 标签属性字符串
|
* @param string $str 标签属性字符串
|
||||||
* @param string $tag 标签名
|
* @param string $name 标签名
|
||||||
|
* @param string $alias 别名
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function parseAttr($str, $tag)
|
public function parseAttr($str, $name, $alias = '')
|
||||||
{
|
{
|
||||||
if (ini_get('magic_quotes_sybase')) {
|
$regex = '/\s+(?>(?<name>[\w-]+)\s*)=(?>\s*)([\"\'])(?<value>(?:(?!\\2).)*)\\2/is';
|
||||||
$str = str_replace('\"', '\'', $str);
|
|
||||||
}
|
|
||||||
$regex = '/\s+(?>(?<name>\w+)\s*)=(?>\s*)([\"\'])(?<value>(?:(?!\\2).)*)\\2/is';
|
|
||||||
$result = [];
|
$result = [];
|
||||||
if (preg_match_all($regex, $str, $matches)) {
|
if (preg_match_all($regex, $str, $matches)) {
|
||||||
foreach ($matches['name'] as $key => $val) {
|
foreach ($matches['name'] as $key => $val) {
|
||||||
$result[$val] = $matches['value'][$key];
|
$result[$val] = $matches['value'][$key];
|
||||||
}
|
}
|
||||||
$tag = strtolower($tag);
|
if (!isset($this->tags[$name])) {
|
||||||
if (!isset($this->tags[$tag])) {
|
|
||||||
// 检测是否存在别名定义
|
// 检测是否存在别名定义
|
||||||
foreach ($this->tags as $key => $val) {
|
foreach ($this->tags as $key => $val) {
|
||||||
if (isset($val['alias']) && in_array($tag, explode(',', $val['alias']))) {
|
if (isset($val['alias'])) {
|
||||||
$item = $val;
|
$array = (array) $val['alias'];
|
||||||
break;
|
if (in_array($name, explode(',', $array[0]))) {
|
||||||
|
$tag = $val;
|
||||||
|
$type = !empty($array[1]) ? $array[1] : 'type';
|
||||||
|
$result[$type] = $name;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$item = $this->tags[$tag];
|
$tag = $this->tags[$name];
|
||||||
|
// 设置了标签别名
|
||||||
|
if (!empty($alias) && isset($tag['alias'])) {
|
||||||
|
$type = !empty($tag['alias'][1]) ? $tag['alias'][1] : 'type';
|
||||||
|
$result[$type] = $alias;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!empty($item['must'])) {
|
if (!empty($tag['must'])) {
|
||||||
$must = explode(',', $item['must']);
|
$must = explode(',', $tag['must']);
|
||||||
foreach ($must as $name) {
|
foreach ($must as $name) {
|
||||||
if (!isset($result[$name])) {
|
if (!isset($result[$name])) {
|
||||||
throw new Exception('_PARAM_ERROR_:' . $name);
|
throw new Exception('_PARAM_ERROR_:' . $name);
|
||||||
@@ -318,18 +261,18 @@ class TagLib
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 允许直接使用表达式的标签
|
// 允许直接使用表达式的标签
|
||||||
if (!empty($this->tags[$tag]['expression'])) {
|
if (!empty($this->tags[$name]['expression'])) {
|
||||||
static $_taglibs;
|
static $_taglibs;
|
||||||
if (!isset($_taglibs[$tag])) {
|
if (!isset($_taglibs[$name])) {
|
||||||
$_taglibs[$tag][0] = strlen(ltrim($this->tpl->config('taglib_begin'), '\\') . $tag);
|
$_taglibs[$name][0] = strlen(ltrim($this->tpl->config('taglib_begin'), '\\') . $name);
|
||||||
$_taglibs[$tag][1] = strlen(ltrim($this->tpl->config('taglib_end'), '\\'));
|
$_taglibs[$name][1] = strlen(ltrim($this->tpl->config('taglib_end'), '\\'));
|
||||||
}
|
}
|
||||||
$result['expression'] = substr($str, $_taglibs[$tag][0], -$_taglibs[$tag][1]);
|
$result['expression'] = substr($str, $_taglibs[$name][0], -$_taglibs[$name][1]);
|
||||||
// 清除自闭合标签尾部/
|
// 清除自闭合标签尾部/
|
||||||
$result['expression'] = rtrim($result['expression'], '/');
|
$result['expression'] = rtrim($result['expression'], '/');
|
||||||
$result['expression'] = trim($result['expression']);
|
$result['expression'] = trim($result['expression']);
|
||||||
} elseif (empty($this->tags[$tag]) || !empty($this->tags[$tag]['attr'])) {
|
} elseif (empty($this->tags[$name]) || !empty($this->tags[$name]['attr'])) {
|
||||||
throw new Exception('_XML_TAG_ERROR_:' . $tag);
|
throw new Exception('_XML_TAG_ERROR_:' . $name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $result;
|
return $result;
|
||||||
@@ -345,7 +288,7 @@ class TagLib
|
|||||||
{
|
{
|
||||||
$condition = str_ireplace(array_keys($this->comparison), array_values($this->comparison), $condition);
|
$condition = str_ireplace(array_keys($this->comparison), array_values($this->comparison), $condition);
|
||||||
$this->tpl->parseVar($condition);
|
$this->tpl->parseVar($condition);
|
||||||
$this->tpl->parseVarFunction($condition); // XXX: 此句能解析表达式中用|分隔的函数,但表达式中如果有|、||这样的逻辑运算就产生了歧异
|
// $this->tpl->parseVarFunction($condition); // XXX: 此句能解析表达式中用|分隔的函数,但表达式中如果有|、||这样的逻辑运算就产生了歧异
|
||||||
return $condition;
|
return $condition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,42 +38,37 @@ class File
|
|||||||
* 读取编译编译
|
* 读取编译编译
|
||||||
* @string $cacheFile 缓存的文件名
|
* @string $cacheFile 缓存的文件名
|
||||||
* @array $vars 变量数组
|
* @array $vars 变量数组
|
||||||
* @boolean $isReturn 是否返回内容
|
* @return void
|
||||||
* @return void|array
|
|
||||||
*/
|
*/
|
||||||
public function read($cacheFile, $vars = [], $isReturn = false)
|
public function read($cacheFile, $vars = [])
|
||||||
{
|
{
|
||||||
if (!empty($vars) && is_array($vars)) {
|
if (!empty($vars) && is_array($vars)) {
|
||||||
// 模板阵列变量分解成为独立变量
|
// 模板阵列变量分解成为独立变量
|
||||||
extract($vars, EXTR_OVERWRITE);
|
extract($vars, EXTR_OVERWRITE);
|
||||||
}
|
}
|
||||||
if ($isReturn) {
|
//载入模版缓存文件
|
||||||
//载入模版缓存文件
|
include $cacheFile;
|
||||||
include $cacheFile;
|
|
||||||
} else {
|
|
||||||
return include $cacheFile;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检查编译缓存是否有效
|
* 检查编译缓存是否有效
|
||||||
* @array $template 用到的模板更新时间列表
|
* @array $templates 用到的模板更新时间列表
|
||||||
* @string $cacheFile 缓存的文件名
|
* @string $cacheFile 缓存的文件名
|
||||||
* @int $cacheTime 缓存时间
|
* @int $cacheTime 缓存时间
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
public function check($files, $cacheFile, $cacheTime)
|
public function check($templates, $cacheFile, $cacheTime)
|
||||||
{
|
{
|
||||||
foreach($files as $time => $path) {
|
|
||||||
if (is_file($path) && filemtime($path) > $time) {
|
|
||||||
// 模板文件如果有更新则缓存需要更新
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (0 != $cacheTime && time() > filemtime($cacheFile) + $cacheTime) {
|
if (0 != $cacheTime && time() > filemtime($cacheFile) + $cacheTime) {
|
||||||
// 缓存是否在有效期
|
// 缓存是否在有效期
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
foreach($templates as $time => $path) {
|
||||||
|
if (is_file($path) && filemtime($path) > $time + $cacheTime) {
|
||||||
|
// 模板文件如果有更新则缓存需要更新
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,43 +57,37 @@ class Sae
|
|||||||
* 读取编译编译
|
* 读取编译编译
|
||||||
* @string $cacheFile 缓存的文件名
|
* @string $cacheFile 缓存的文件名
|
||||||
* @array $vars 变量数组
|
* @array $vars 变量数组
|
||||||
* @boolean $isReturn 是否返回内容
|
* @return void
|
||||||
* @return void|array
|
|
||||||
*/
|
*/
|
||||||
public function read($cacheFile, $vars = [], $isReturn = false)
|
public function read($cacheFile, $vars = [])
|
||||||
{
|
{
|
||||||
if (!empty($vars) && is_array($vars)) {
|
if (!empty($vars) && is_array($vars)) {
|
||||||
extract($vars, EXTR_OVERWRITE);
|
extract($vars, EXTR_OVERWRITE);
|
||||||
}
|
}
|
||||||
if ($isReturn) {
|
eval('?>' . $this->get($cacheFile, 'content'));
|
||||||
return $this->get($cacheFile, 'content');
|
|
||||||
} else {
|
|
||||||
eval('?>' . $this->get($cacheFile, 'content'));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检查编译缓存是否有效
|
* 检查编译缓存是否有效
|
||||||
* @array $template 用到的模板更新时间列表
|
* @array $templates 用到的模板更新时间列表
|
||||||
* @string $cacheFile 缓存的文件名
|
* @string $cacheFile 缓存的文件名
|
||||||
* @int $cacheTime 缓存时间
|
* @int $cacheTime 缓存时间
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
public function check($template, $cacheFile, $cacheTime)
|
public function check($templates, $cacheFile, $cacheTime)
|
||||||
{
|
{
|
||||||
foreach($template as $time => $path) {
|
|
||||||
if (is_file($path) && filemtime($path) > $time) {
|
|
||||||
// 模板文件如果有更新则缓存需要更新
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$mtime = $this->get($cacheFile, 'mtime');
|
$mtime = $this->get($cacheFile, 'mtime');
|
||||||
if (0 != $cacheTime && time() > $mtime + $cacheTime) {
|
if (0 != $cacheTime && time() > $mtime + $cacheTime) {
|
||||||
// 缓存是否在有效期
|
// 缓存是否在有效期
|
||||||
return false;
|
return false;
|
||||||
} else {
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
foreach($templates as $time => $path) {
|
||||||
|
if (is_file($path) && filemtime($path) > $time + $cacheTime) {
|
||||||
|
// 模板文件如果有更新则缓存需要更新
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -35,23 +35,27 @@ class Cx extends Taglib
|
|||||||
'switch' => ['attr' => 'name', 'expression' => true],
|
'switch' => ['attr' => 'name', 'expression' => true],
|
||||||
'case' => ['attr' => 'value,break', 'expression' => true],
|
'case' => ['attr' => 'value,break', 'expression' => true],
|
||||||
'default' => ['attr' => '', 'close' => 0],
|
'default' => ['attr' => '', 'close' => 0],
|
||||||
'compare' => ['attr' => 'name,value,type', 'alias' => 'eq,equal,notequal,neq,gt,lt,egt,elt,heq,nheq'],
|
'compare' => ['attr' => 'name,value,type', 'alias' => ['eq,equal,notequal,neq,gt,lt,egt,elt,heq,nheq', 'type']],
|
||||||
'range' => ['attr' => 'name,value,type', 'alias' => 'in,notin,between,notbetween'],
|
'range' => ['attr' => 'name,value,type', 'alias' => ['in,notin,between,notbetween', 'type']],
|
||||||
'empty' => ['attr' => 'name'],
|
'empty' => ['attr' => 'name'],
|
||||||
'notempty' => ['attr' => 'name'],
|
'notempty' => ['attr' => 'name'],
|
||||||
'present' => ['attr' => 'name'],
|
'present' => ['attr' => 'name'],
|
||||||
'notpresent' => ['attr' => 'name'],
|
'notpresent' => ['attr' => 'name'],
|
||||||
'defined' => ['attr' => 'name'],
|
'defined' => ['attr' => 'name'],
|
||||||
'notdefined' => ['attr' => 'name'],
|
'notdefined' => ['attr' => 'name'],
|
||||||
'import' => ['attr' => 'file,href,type,value,basepath', 'close' => 0, 'alias' => 'load,css,js'],
|
'import' => ['attr' => 'file,href,type,value,basepath', 'close' => 0],
|
||||||
|
'load' => ['attr' => 'file,href,type,value,basepath', 'close' => 0, 'alias' => ['css,js', 'type']],
|
||||||
'assign' => ['attr' => 'name,value', 'close' => 0],
|
'assign' => ['attr' => 'name,value', 'close' => 0],
|
||||||
'define' => ['attr' => 'name,value', 'close' => 0],
|
'define' => ['attr' => 'name,value', 'close' => 0],
|
||||||
'for' => ['attr' => 'start,end,name,comparison,step'],
|
'for' => ['attr' => 'start,end,name,comparison,step'],
|
||||||
'url' => ['attr' => 'link,vars,suffix,domain', 'close' => 0, 'expression' => true],
|
'url' => ['attr' => 'link,vars,suffix,domain', 'close' => 0, 'expression' => true],
|
||||||
|
'function' => ['attr' => 'name,vars,use,call'],
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* php标签解析
|
* php标签解析
|
||||||
|
* 格式:
|
||||||
|
* {php}echo $name{/php}
|
||||||
* @access public
|
* @access public
|
||||||
* @param array $tag 标签属性
|
* @param array $tag 标签属性
|
||||||
* @param string $content 标签内容
|
* @param string $content 标签内容
|
||||||
@@ -66,10 +70,10 @@ class Cx extends Taglib
|
|||||||
/**
|
/**
|
||||||
* volist标签解析 循环输出数据集
|
* volist标签解析 循环输出数据集
|
||||||
* 格式:
|
* 格式:
|
||||||
* <volist name="userList" id="user" empty="" >
|
* {volist name="userList" id="user" empty=""}
|
||||||
* {user.username}
|
* {user.username}
|
||||||
* {user.email}
|
* {user.email}
|
||||||
* </volist>
|
* {/volist}
|
||||||
* @access public
|
* @access public
|
||||||
* @param array $tag 标签属性
|
* @param array $tag 标签属性
|
||||||
* @param string $content 标签内容
|
* @param string $content 标签内容
|
||||||
@@ -117,6 +121,10 @@ class Cx extends Taglib
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* foreach标签解析 循环输出数据集
|
* foreach标签解析 循环输出数据集
|
||||||
|
* 格式:
|
||||||
|
* {foreach name="userList" id="user" key="key" index="i" mod="2" offset="3" length="5" empty=""}
|
||||||
|
* {user.username}
|
||||||
|
* {/foreach}
|
||||||
* @access public
|
* @access public
|
||||||
* @param array $tag 标签属性
|
* @param array $tag 标签属性
|
||||||
* @param string $content 标签内容
|
* @param string $content 标签内容
|
||||||
@@ -192,10 +200,10 @@ class Cx extends Taglib
|
|||||||
/**
|
/**
|
||||||
* if标签解析
|
* if标签解析
|
||||||
* 格式:
|
* 格式:
|
||||||
* <if condition=" $a eq 1" >
|
* {if condition=" $a eq 1"}
|
||||||
* <elseif condition="$a eq 2" />
|
* {elseif condition="$a eq 2" /}
|
||||||
* <else />
|
* {else /}
|
||||||
* </if>
|
* {/if}
|
||||||
* 表达式支持 eq neq gt egt lt elt == > >= < <= or and || &&
|
* 表达式支持 eq neq gt egt lt elt == > >= < <= or and || &&
|
||||||
* @access public
|
* @access public
|
||||||
* @param array $tag 标签属性
|
* @param array $tag 标签属性
|
||||||
@@ -211,7 +219,7 @@ class Cx extends Taglib
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* else标签解析
|
* elseif标签解析
|
||||||
* 格式:见if标签
|
* 格式:见if标签
|
||||||
* @access public
|
* @access public
|
||||||
* @param array $tag 标签属性
|
* @param array $tag 标签属性
|
||||||
@@ -228,6 +236,7 @@ class Cx extends Taglib
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* else标签解析
|
* else标签解析
|
||||||
|
* 格式:见if标签
|
||||||
* @access public
|
* @access public
|
||||||
* @param array $tag 标签属性
|
* @param array $tag 标签属性
|
||||||
* @return string
|
* @return string
|
||||||
@@ -241,11 +250,11 @@ class Cx extends Taglib
|
|||||||
/**
|
/**
|
||||||
* switch标签解析
|
* switch标签解析
|
||||||
* 格式:
|
* 格式:
|
||||||
* <switch name="a.name" >
|
* {switch name="a.name"}
|
||||||
* <case value="1" break="false">1</case>
|
* {case value="1" break="false"}1{/case}
|
||||||
* <case value="2" >2</case>
|
* {case value="2" }2{/case}
|
||||||
* <default />other
|
* {default /}other
|
||||||
* </switch>
|
* {/switch}
|
||||||
* @access public
|
* @access public
|
||||||
* @param array $tag 标签属性
|
* @param array $tag 标签属性
|
||||||
* @param string $content 标签内容
|
* @param string $content 标签内容
|
||||||
@@ -292,7 +301,7 @@ class Cx extends Taglib
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* default标签解析 需要配合switch才有效
|
* default标签解析 需要配合switch才有效
|
||||||
* 使用: <default />ddfdf
|
* 使用: {default /}ddfdf
|
||||||
* @access public
|
* @access public
|
||||||
* @param array $tag 标签属性
|
* @param array $tag 标签属性
|
||||||
* @param string $content 标签内容
|
* @param string $content 标签内容
|
||||||
@@ -307,18 +316,17 @@ class Cx extends Taglib
|
|||||||
/**
|
/**
|
||||||
* compare标签解析
|
* compare标签解析
|
||||||
* 用于值的比较 支持 eq neq gt lt egt elt heq nheq 默认是eq
|
* 用于值的比较 支持 eq neq gt lt egt elt heq nheq 默认是eq
|
||||||
* 格式: <compare name="" type="eq" value="" >content</compare>
|
* 格式: {compare name="" type="eq" value="" }content{/compare}
|
||||||
* @access public
|
* @access public
|
||||||
* @param array $tag 标签属性
|
* @param array $tag 标签属性
|
||||||
* @param string $content 标签内容
|
* @param string $content 标签内容
|
||||||
* @param string $type 比较类型
|
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function _compare($tag, $content, $type = 'eq')
|
public function _compare($tag, $content)
|
||||||
{
|
{
|
||||||
$name = $tag['name'];
|
$name = $tag['name'];
|
||||||
$value = $tag['value'];
|
$value = $tag['value'];
|
||||||
$type = isset($tag['type']) ? $tag['type'] : $type;
|
$type = isset($tag['type']) ? $tag['type'] : 'eq'; // 比较类型
|
||||||
$name = $this->autoBuildVar($name);
|
$name = $this->autoBuildVar($name);
|
||||||
$flag = substr($value, 0, 1);
|
$flag = substr($value, 0, 1);
|
||||||
if ('$' == $flag || ':' == $flag) {
|
if ('$' == $flag || ':' == $flag) {
|
||||||
@@ -326,77 +334,34 @@ class Cx extends Taglib
|
|||||||
} else {
|
} else {
|
||||||
$value = '\'' . $value . '\'';
|
$value = '\'' . $value . '\'';
|
||||||
}
|
}
|
||||||
|
switch($type) {
|
||||||
|
case 'equal':
|
||||||
|
$type = 'eq';
|
||||||
|
break;
|
||||||
|
case 'notequal':
|
||||||
|
$type = 'neq';
|
||||||
|
break;
|
||||||
|
}
|
||||||
$type = $this->parseCondition(' ' . $type . ' ');
|
$type = $this->parseCondition(' ' . $type . ' ');
|
||||||
$parseStr = '<?php if(' . $name . ' ' . $type . ' ' . $value . '): ?>' . $content . '<?php endif; ?>';
|
$parseStr = '<?php if(' . $name . ' ' . $type . ' ' . $value . '): ?>' . $content . '<?php endif; ?>';
|
||||||
return $parseStr;
|
return $parseStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function _eq($tag, $content)
|
|
||||||
{
|
|
||||||
return $this->_compare($tag, $content, 'eq');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function _equal($tag, $content)
|
|
||||||
{
|
|
||||||
return $this->_compare($tag, $content, 'eq');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function _neq($tag, $content)
|
|
||||||
{
|
|
||||||
return $this->_compare($tag, $content, 'neq');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function _notequal($tag, $content)
|
|
||||||
{
|
|
||||||
return $this->_compare($tag, $content, 'neq');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function _gt($tag, $content)
|
|
||||||
{
|
|
||||||
return $this->_compare($tag, $content, 'gt');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function _lt($tag, $content)
|
|
||||||
{
|
|
||||||
return $this->_compare($tag, $content, 'lt');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function _egt($tag, $content)
|
|
||||||
{
|
|
||||||
return $this->_compare($tag, $content, 'egt');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function _elt($tag, $content)
|
|
||||||
{
|
|
||||||
return $this->_compare($tag, $content, 'elt');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function _heq($tag, $content)
|
|
||||||
{
|
|
||||||
return $this->_compare($tag, $content, 'heq');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function _nheq($tag, $content)
|
|
||||||
{
|
|
||||||
return $this->_compare($tag, $content, 'nheq');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* range标签解析
|
* range标签解析
|
||||||
* 如果某个变量存在于某个范围 则输出内容 type= in 表示在范围内 否则表示在范围外
|
* 如果某个变量存在于某个范围 则输出内容 type= in 表示在范围内 否则表示在范围外
|
||||||
* 格式: <range name="var|function" value="val" type='in|notin' >content</range>
|
* 格式: {range name="var|function" value="val" type='in|notin' }content{/range}
|
||||||
* example: <range name="a" value="1,2,3" type='in' >content</range>
|
* example: {range name="a" value="1,2,3" type='in' }content{/range}
|
||||||
* @access public
|
* @access public
|
||||||
* @param array $tag 标签属性
|
* @param array $tag 标签属性
|
||||||
* @param string $content 标签内容
|
* @param string $content 标签内容
|
||||||
* @param string $type 比较类型
|
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function _range($tag, $content, $type = 'in')
|
public function _range($tag, $content)
|
||||||
{
|
{
|
||||||
$name = $tag['name'];
|
$name = $tag['name'];
|
||||||
$value = $tag['value'];
|
$value = $tag['value'];
|
||||||
$type = isset($tag['type']) ? $tag['type'] : $type;
|
$type = isset($tag['type']) ? $tag['type'] : 'in'; // 比较类型
|
||||||
|
|
||||||
$name = $this->autoBuildVar($name);
|
$name = $this->autoBuildVar($name);
|
||||||
$flag = substr($value, 0, 1);
|
$flag = substr($value, 0, 1);
|
||||||
@@ -418,32 +383,10 @@ class Cx extends Taglib
|
|||||||
return $parseStr;
|
return $parseStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// range标签的别名 用于in判断
|
|
||||||
public function _in($tag, $content)
|
|
||||||
{
|
|
||||||
return $this->_range($tag, $content, 'in');
|
|
||||||
}
|
|
||||||
|
|
||||||
// range标签的别名 用于notin判断
|
|
||||||
public function _notin($tag, $content)
|
|
||||||
{
|
|
||||||
return $this->_range($tag, $content, 'notin');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function _between($tag, $content)
|
|
||||||
{
|
|
||||||
return $this->_range($tag, $content, 'between');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function _notbetween($tag, $content)
|
|
||||||
{
|
|
||||||
return $this->_range($tag, $content, 'notbetween');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* present标签解析
|
* present标签解析
|
||||||
* 如果某个变量已经设置 则输出内容
|
* 如果某个变量已经设置 则输出内容
|
||||||
* 格式: <present name="" >content</present>
|
* 格式: {present name="" }content{/present}
|
||||||
* @access public
|
* @access public
|
||||||
* @param array $tag 标签属性
|
* @param array $tag 标签属性
|
||||||
* @param string $content 标签内容
|
* @param string $content 标签内容
|
||||||
@@ -460,7 +403,7 @@ class Cx extends Taglib
|
|||||||
/**
|
/**
|
||||||
* notpresent标签解析
|
* notpresent标签解析
|
||||||
* 如果某个变量没有设置,则输出内容
|
* 如果某个变量没有设置,则输出内容
|
||||||
* 格式: <notpresent name="" >content</notpresent>
|
* 格式: {notpresent name="" }content{/notpresent}
|
||||||
* @access public
|
* @access public
|
||||||
* @param array $tag 标签属性
|
* @param array $tag 标签属性
|
||||||
* @param string $content 标签内容
|
* @param string $content 标签内容
|
||||||
@@ -477,7 +420,7 @@ class Cx extends Taglib
|
|||||||
/**
|
/**
|
||||||
* empty标签解析
|
* empty标签解析
|
||||||
* 如果某个变量为empty 则输出内容
|
* 如果某个变量为empty 则输出内容
|
||||||
* 格式: <empty name="" >content</empty>
|
* 格式: {empty name="" }content{/empty}
|
||||||
* @access public
|
* @access public
|
||||||
* @param array $tag 标签属性
|
* @param array $tag 标签属性
|
||||||
* @param string $content 标签内容
|
* @param string $content 标签内容
|
||||||
@@ -491,6 +434,15 @@ class Cx extends Taglib
|
|||||||
return $parseStr;
|
return $parseStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* notempty标签解析
|
||||||
|
* 如果某个变量不为empty 则输出内容
|
||||||
|
* 格式: {notempty name="" }content{/notempty}
|
||||||
|
* @access public
|
||||||
|
* @param array $tag 标签属性
|
||||||
|
* @param string $content 标签内容
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
public function _notempty($tag, $content)
|
public function _notempty($tag, $content)
|
||||||
{
|
{
|
||||||
$name = $tag['name'];
|
$name = $tag['name'];
|
||||||
@@ -501,7 +453,7 @@ class Cx extends Taglib
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 判断是否已经定义了该常量
|
* 判断是否已经定义了该常量
|
||||||
* <defined name='TXT'>已定义</defined>
|
* {defined name='TXT'}已定义{/defined}
|
||||||
* @param array $tag
|
* @param array $tag
|
||||||
* @param string $content
|
* @param string $content
|
||||||
* @return string
|
* @return string
|
||||||
@@ -513,6 +465,13 @@ class Cx extends Taglib
|
|||||||
return $parseStr;
|
return $parseStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否没有定义了该常量
|
||||||
|
* {notdefined name='TXT'}已定义{/notdefined}
|
||||||
|
* @param array $tag
|
||||||
|
* @param string $content
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
public function _notdefined($tag, $content)
|
public function _notdefined($tag, $content)
|
||||||
{
|
{
|
||||||
$name = $tag['name'];
|
$name = $tag['name'];
|
||||||
@@ -521,8 +480,8 @@ class Cx extends Taglib
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* import 标签解析 <import file="Js.Base" />
|
* import 标签解析 {import file="Js.Base" /}
|
||||||
* <import file="Css.Base" type="css" />
|
* 格式:{import file="Css.Base" type="css" /}
|
||||||
* @access public
|
* @access public
|
||||||
* @param array $tag 标签属性
|
* @param array $tag 标签属性
|
||||||
* @param string $content 标签内容
|
* @param string $content 标签内容
|
||||||
@@ -530,9 +489,10 @@ class Cx extends Taglib
|
|||||||
* @param string $type 类型
|
* @param string $type 类型
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function _import($tag, $content, $isFile = false, $type = '')
|
public function _import($tag, $content, $isFile = false)
|
||||||
{
|
{
|
||||||
$file = isset($tag['file']) ? $tag['file'] : $tag['href'];
|
$file = isset($tag['file']) ? $tag['file'] : $tag['href'];
|
||||||
|
$type = isset($tag['type']) ? strtolower($tag['type']) : ($isFile ? null : 'js');
|
||||||
$parseStr = '';
|
$parseStr = '';
|
||||||
$endStr = '';
|
$endStr = '';
|
||||||
// 判断是否存在加载条件 允许使用函数判断(默认为isset)
|
// 判断是否存在加载条件 允许使用函数判断(默认为isset)
|
||||||
@@ -544,8 +504,6 @@ class Cx extends Taglib
|
|||||||
$endStr = '<?php endif; ?>';
|
$endStr = '<?php endif; ?>';
|
||||||
}
|
}
|
||||||
if ($isFile) {
|
if ($isFile) {
|
||||||
// 根据文件名后缀自动识别
|
|
||||||
$type = $type ? $type : (!empty($tag['type']) ? strtolower($tag['type']) : null);
|
|
||||||
// 文件方式导入
|
// 文件方式导入
|
||||||
$array = explode(',', $file);
|
$array = explode(',', $file);
|
||||||
foreach ($array as $val) {
|
foreach ($array as $val) {
|
||||||
@@ -565,8 +523,7 @@ class Cx extends Taglib
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 命名空间导入模式 默认是js
|
// 命名空间导入模式
|
||||||
$type = $type ? $type : (!empty($tag['type']) ? strtolower($tag['type']) : 'js');
|
|
||||||
$basepath = !empty($tag['basepath']) ? $tag['basepath'] : '/Public';
|
$basepath = !empty($tag['basepath']) ? $tag['basepath'] : '/Public';
|
||||||
// 命名空间方式导入外部文件
|
// 命名空间方式导入外部文件
|
||||||
$array = explode(',', $file);
|
$array = explode(',', $file);
|
||||||
@@ -584,7 +541,7 @@ class Cx extends Taglib
|
|||||||
$parseStr .= '<link rel="stylesheet" type="text/css" href="' . $basepath . '/' . str_replace(['.', '#'], ['/', '.'], $val) . '.css' . ($version ? '?' . $version : '') . '" />';
|
$parseStr .= '<link rel="stylesheet" type="text/css" href="' . $basepath . '/' . str_replace(['.', '#'], ['/', '.'], $val) . '.css' . ($version ? '?' . $version : '') . '" />';
|
||||||
break;
|
break;
|
||||||
case 'php':
|
case 'php':
|
||||||
$parseStr .= '<?php import("' . $val . '"); ?>';
|
$parseStr .= '<?php \think\Loader::import("' . $val . '"); ?>';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -598,22 +555,10 @@ class Cx extends Taglib
|
|||||||
return $this->_import($tag, $content, true);
|
return $this->_import($tag, $content, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// import别名使用 导入css文件 <css file="__PUBLIC__/Css/Base.css" />
|
|
||||||
public function _css($tag, $content)
|
|
||||||
{
|
|
||||||
return $this->_import($tag, $content, true, 'css');
|
|
||||||
}
|
|
||||||
|
|
||||||
// import别名使用 导入js文件 <js file="__PUBLIC__/Js/Base.js" />
|
|
||||||
public function _js($tag, $content)
|
|
||||||
{
|
|
||||||
return $this->_import($tag, $content, true, 'js');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* assign标签解析
|
* assign标签解析
|
||||||
* 在模板中给某个变量赋值 支持变量赋值
|
* 在模板中给某个变量赋值 支持变量赋值
|
||||||
* 格式: <assign name="" value="" />
|
* 格式: {assign name="" value="" /}
|
||||||
* @access public
|
* @access public
|
||||||
* @param array $tag 标签属性
|
* @param array $tag 标签属性
|
||||||
* @param string $content 标签内容
|
* @param string $content 标签内容
|
||||||
@@ -635,7 +580,7 @@ class Cx extends Taglib
|
|||||||
/**
|
/**
|
||||||
* define标签解析
|
* define标签解析
|
||||||
* 在模板中定义常量 支持变量赋值
|
* 在模板中定义常量 支持变量赋值
|
||||||
* 格式: <define name="" value="" />
|
* 格式: {define name="" value="" /}
|
||||||
* @access public
|
* @access public
|
||||||
* @param array $tag 标签属性
|
* @param array $tag 标签属性
|
||||||
* @param string $content 标签内容
|
* @param string $content 标签内容
|
||||||
@@ -656,7 +601,10 @@ class Cx extends Taglib
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* for标签解析
|
* for标签解析
|
||||||
* 格式: <for start="" end="" comparison="" step="" name="" />
|
* 格式:
|
||||||
|
* {for start="" end="" comparison="" step="" name=""}
|
||||||
|
* content
|
||||||
|
* {/for}
|
||||||
* @access public
|
* @access public
|
||||||
* @param array $tag 标签属性
|
* @param array $tag 标签属性
|
||||||
* @param string $content 标签内容
|
* @param string $content 标签内容
|
||||||
@@ -721,4 +669,38 @@ class Cx extends Taglib
|
|||||||
$domain = isset($tag['domain']) ? $tag['domain'] : 'false';
|
$domain = isset($tag['domain']) ? $tag['domain'] : 'false';
|
||||||
return '<?php echo U("' . $url . '","' . $vars . '",' . $suffix . ',' . $domain . ');?>';
|
return '<?php echo U("' . $url . '","' . $vars . '",' . $suffix . ',' . $domain . ');?>';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* function标签解析 匿名函数,可实现递归
|
||||||
|
* 使用:
|
||||||
|
* {function name="func" vars="$data" call="$list" use="&$a,&$b"}
|
||||||
|
* {if is_array($data)}
|
||||||
|
* {foreach $data as $val}
|
||||||
|
* {~func($val) /}
|
||||||
|
* {/foreach}
|
||||||
|
* {else /}
|
||||||
|
* {$data}
|
||||||
|
* {/if}
|
||||||
|
* {/function}
|
||||||
|
* @access public
|
||||||
|
* @param array $tag 标签属性
|
||||||
|
* @param string $content 标签内容
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function _function($tag, $content)
|
||||||
|
{
|
||||||
|
$name = !empty($tag['name']) ? $tag['name'] : 'func';
|
||||||
|
$vars = !empty($tag['vars']) ? $tag['vars'] : '';
|
||||||
|
$call = !empty($tag['call']) ? $tag['call'] : '';
|
||||||
|
$use = ['&$' . $name];
|
||||||
|
if (!empty($tag['use'])) {
|
||||||
|
foreach (explode(',', $tag['use']) as $val) {
|
||||||
|
$use[] = '&' . ltrim(trim($val), '&');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$parseStr = '<?php $' . $name . '=function(' . $vars . ') use(' . implode(',', $use) . ') {';
|
||||||
|
$parseStr .= ' ?>' . $content . '<?php }; ';
|
||||||
|
$parseStr .= $call ? '$' . $name . '(' . $call . '); ?>' : '?>';
|
||||||
|
return $parseStr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,2 @@
|
|||||||
{extend name="extend2" /}
|
{extend name="extend2" /}
|
||||||
{block name="mainbody"}
|
{block name="head"}header{/block}
|
||||||
mainbody
|
|
||||||
{/block}
|
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
{layout name="layout2" replace="[__REPLACE__]" /}
|
{layout name="layout2" replace="[__REPLACE__]" /}
|
||||||
<div>
|
{block name="head"}{/block}
|
||||||
|
<div id="wrap">
|
||||||
{include file="include" name="info" value="$info.value" /}
|
{include file="include" name="info" value="$info.value" /}
|
||||||
{block name="main"}
|
{block name="main"}
|
||||||
{block name="side"}
|
{block name="side"}
|
||||||
|
|||||||
@@ -469,7 +469,7 @@ EOF;
|
|||||||
{import file="base,common" type="php" /}
|
{import file="base,common" type="php" /}
|
||||||
EOF;
|
EOF;
|
||||||
$data = <<<EOF
|
$data = <<<EOF
|
||||||
<?php import("base"); ?><?php import("common"); ?>
|
<?php \\think\\Loader::import("base"); ?><?php \\think\\Loader::import("common"); ?>
|
||||||
EOF;
|
EOF;
|
||||||
$cx->parseTag($content);
|
$cx->parseTag($content);
|
||||||
$this->assertEquals($content, $data);
|
$this->assertEquals($content, $data);
|
||||||
@@ -563,4 +563,31 @@ EOF;
|
|||||||
$this->expectOutputString('123456789');
|
$this->expectOutputString('123456789');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testFunction()
|
||||||
|
{
|
||||||
|
$template = new template();
|
||||||
|
$data = [
|
||||||
|
'list' => ['language' => 'php', 'version' => ['5.4', '5.5']],
|
||||||
|
'a' => '[',
|
||||||
|
'b' => ']',
|
||||||
|
];
|
||||||
|
|
||||||
|
$content = <<<EOF
|
||||||
|
{function name="func" vars="\$data" call="\$list" use="&\$a,&\$b"}
|
||||||
|
{foreach \$data as \$key=>\$val}
|
||||||
|
{if is_array(\$val)}
|
||||||
|
{~\$func(\$val)}
|
||||||
|
{else}
|
||||||
|
{if !is_numeric(\$key)}
|
||||||
|
{\$key.':'.\$val.','}
|
||||||
|
{else}
|
||||||
|
{\$a.\$val.\$b}
|
||||||
|
{/if}
|
||||||
|
{/if}
|
||||||
|
{/foreach}
|
||||||
|
{/function}
|
||||||
|
EOF;
|
||||||
|
$template->fetch($content, $data);
|
||||||
|
$this->expectOutputString("language:php,[5.4][5.5]");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -216,6 +216,16 @@ EOF;
|
|||||||
$template->parse($content);
|
$template->parse($content);
|
||||||
$this->assertEquals($data, $content);
|
$this->assertEquals($data, $content);
|
||||||
|
|
||||||
|
$content = <<<EOF
|
||||||
|
<#\$info.a?='test'#>
|
||||||
|
EOF;
|
||||||
|
$data = <<<EOF
|
||||||
|
<?php if((is_array(\$info)?\$info['a']:\$info->a)) echo 'test'; ?>
|
||||||
|
EOF;
|
||||||
|
|
||||||
|
$template->parse($content);
|
||||||
|
$this->assertEquals($data, $content);
|
||||||
|
|
||||||
$content = <<<EOF
|
$content = <<<EOF
|
||||||
<#\$info.a==\$info.b?='test'#>
|
<#\$info.a==\$info.b?='test'#>
|
||||||
EOF;
|
EOF;
|
||||||
@@ -332,17 +342,29 @@ EOF;
|
|||||||
|
|
||||||
$content = <<<EOF
|
$content = <<<EOF
|
||||||
{extend name="\$files.extend" /}
|
{extend name="\$files.extend" /}
|
||||||
|
{block name="main"}
|
||||||
|
main
|
||||||
{block name="side"}
|
{block name="side"}
|
||||||
|
{__BLOCK__}
|
||||||
{include file="\$files.include" name="\$user.name" value="\$user.account" /}
|
{include file="\$files.include" name="\$user.name" value="\$user.account" /}
|
||||||
{\$message}{literal}{\$message}{/literal}
|
{\$message}{literal}{\$message}{/literal}
|
||||||
{/block}
|
{/block}
|
||||||
|
{block name="mainbody"}
|
||||||
|
mainbody
|
||||||
|
{/block}
|
||||||
|
{/block}
|
||||||
EOF;
|
EOF;
|
||||||
$content2 = <<<EOF
|
$content2 = <<<EOF
|
||||||
<nav>
|
<nav>
|
||||||
<div>
|
header
|
||||||
|
<div id="wrap">
|
||||||
<input name="info" value="value">
|
<input name="info" value="value">
|
||||||
value:
|
value:
|
||||||
|
|
||||||
|
main
|
||||||
|
|
||||||
|
|
||||||
|
side
|
||||||
|
|
||||||
<input name="name" value="100">
|
<input name="name" value="100">
|
||||||
value:
|
value:
|
||||||
@@ -360,6 +382,8 @@ value:
|
|||||||
EOF;
|
EOF;
|
||||||
$template->fetch($content);
|
$template->fetch($content);
|
||||||
$this->expectOutputString($content2);
|
$this->expectOutputString($content2);
|
||||||
|
// $template->parse($content);
|
||||||
|
// var_dump($content);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testVarAssign()
|
public function testVarAssign()
|
||||||
|
|||||||
Reference in New Issue
Block a user