优代部分代码;block标签内可以使用{__block__}来引用所继承模板中相应block标签的内容;

模板包含文件记录及更新时间直接写入缓存的模板中;改进标签别名的处理方式,别名不再定义方法;
去除include标签传参自动生成变量的代码;cx类增加function方法,用来生成匿名函数,结合{~$函数名()}可用于递归的实现。
This commit is contained in:
oldrind
2016-03-11 21:58:18 +08:00
parent 542a3333d6
commit 71dbdcb874
9 changed files with 390 additions and 413 deletions

View File

@@ -87,15 +87,15 @@ class TagLib
public function parseTag(&$content, $lib = '')
{
$tags = [];
$_lib = $lib ? $lib . ':' : '';
foreach ($this->tags as $name => $val) {
$close = !isset($val['close']) || $val['close'] ? 1 : 0;
$_key = $lib ? $lib . ':' . $name : $name;
$tags[$close][$_key] = $name;
$close = !isset($val['close']) || $val['close'] ? 1 : 0;
$tags[$close][$_lib . $name] = $name;
if (isset($val['alias'])) {
// 别名设置
foreach (explode(',', $val['alias']) as $v) {
$_key = $lib ? $lib . ':' . $v : $v;
$tags[$close][$_key] = $v;
$array = (array) $val['alias'];
foreach (explode(',', $array[0]) as $v) {
$tags[$close][$_lib . $v] = $name;
}
}
}
@@ -117,8 +117,6 @@ class TagLib
'begin' => array_pop($right[$name]), // 标签开始符
'end' => $match[0], // 标签结束符
];
} else {
continue;
}
} else {
// 标签头压入栈
@@ -136,9 +134,10 @@ class TagLib
// 标签替换 从后向前
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;
// 读取标签库中对应的标签内容 replace[0]用来替换标签头replace[1]用来替换标签尾
$replace = explode($break, $this->$method($attrs, $break));
@@ -171,11 +170,12 @@ class TagLib
// 自闭合标签
if (!empty($tags[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;
return $this->$method($attrs, '');
}, $content);
@@ -192,14 +192,10 @@ class TagLib
*/
private function getRegex($tags, $close)
{
$begin = $this->tpl->config('taglib_begin');
$end = $this->tpl->config('taglib_end');
$single = strlen(ltrim($begin, '\\')) == 1 && strlen(ltrim($end, '\\')) == 1 ? true : false;
if (is_array($tags)) {
$tagName = implode('|', $tags);
} else {
$tagName = $tags;
}
$begin = $this->tpl->config('taglib_begin');
$end = $this->tpl->config('taglib_end');
$single = strlen(ltrim($begin, '\\')) == 1 && strlen(ltrim($end, '\\')) == 1 ? true : false;
$tagName = is_array($tags) ? implode('|', $tags) : $tags;
if ($single) {
if ($close) {
// 如果是闭合标签
@@ -218,98 +214,45 @@ class TagLib
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
* @param string $str 标签属性字符串
* @param string $tag 标签名
* @param string $name 标签名
* @param string $alias 别名
* @return array
*/
public function parseAttr($str, $tag)
public function parseAttr($str, $name, $alias = '')
{
if (ini_get('magic_quotes_sybase')) {
$str = str_replace('\"', '\'', $str);
}
$regex = '/\s+(?>(?<name>\w+)\s*)=(?>\s*)([\"\'])(?<value>(?:(?!\\2).)*)\\2/is';
$regex = '/\s+(?>(?<name>[\w-]+)\s*)=(?>\s*)([\"\'])(?<value>(?:(?!\\2).)*)\\2/is';
$result = [];
if (preg_match_all($regex, $str, $matches)) {
foreach ($matches['name'] as $key => $val) {
$result[$val] = $matches['value'][$key];
}
$tag = strtolower($tag);
if (!isset($this->tags[$tag])) {
if (!isset($this->tags[$name])) {
// 检测是否存在别名定义
foreach ($this->tags as $key => $val) {
if (isset($val['alias']) && in_array($tag, explode(',', $val['alias']))) {
$item = $val;
break;
if (isset($val['alias'])) {
$array = (array) $val['alias'];
if (in_array($name, explode(',', $array[0]))) {
$tag = $val;
$type = !empty($array[1]) ? $array[1] : 'type';
$result[$type] = $name;
break;
}
}
}
} 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'])) {
$must = explode(',', $item['must']);
if (!empty($tag['must'])) {
$must = explode(',', $tag['must']);
foreach ($must as $name) {
if (!isset($result[$name])) {
throw new Exception('_PARAM_ERROR_:' . $name);
@@ -318,18 +261,18 @@ class TagLib
}
} else {
// 允许直接使用表达式的标签
if (!empty($this->tags[$tag]['expression'])) {
if (!empty($this->tags[$name]['expression'])) {
static $_taglibs;
if (!isset($_taglibs[$tag])) {
$_taglibs[$tag][0] = strlen(ltrim($this->tpl->config('taglib_begin'), '\\') . $tag);
$_taglibs[$tag][1] = strlen(ltrim($this->tpl->config('taglib_end'), '\\'));
if (!isset($_taglibs[$name])) {
$_taglibs[$name][0] = strlen(ltrim($this->tpl->config('taglib_begin'), '\\') . $name);
$_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'] = trim($result['expression']);
} elseif (empty($this->tags[$tag]) || !empty($this->tags[$tag]['attr'])) {
throw new Exception('_XML_TAG_ERROR_:' . $tag);
} elseif (empty($this->tags[$name]) || !empty($this->tags[$name]['attr'])) {
throw new Exception('_XML_TAG_ERROR_:' . $name);
}
}
return $result;
@@ -345,7 +288,7 @@ class TagLib
{
$condition = str_ireplace(array_keys($this->comparison), array_values($this->comparison), $condition);
$this->tpl->parseVar($condition);
$this->tpl->parseVarFunction($condition); // XXX: 此句能解析表达式中用|分隔的函数,但表达式中如果有|、||这样的逻辑运算就产生了歧异
// $this->tpl->parseVarFunction($condition); // XXX: 此句能解析表达式中用|分隔的函数,但表达式中如果有|、||这样的逻辑运算就产生了歧异
return $condition;
}

View File

@@ -38,42 +38,37 @@ class File
* 读取编译编译
* @string $cacheFile 缓存的文件名
* @array $vars 变量数组
* @boolean $isReturn 是否返回内容
* @return void|array
* @return void
*/
public function read($cacheFile, $vars = [], $isReturn = false)
public function read($cacheFile, $vars = [])
{
if (!empty($vars) && is_array($vars)) {
// 模板阵列变量分解成为独立变量
extract($vars, EXTR_OVERWRITE);
}
if ($isReturn) {
//载入模版缓存文件
include $cacheFile;
} else {
return include $cacheFile;
}
//载入模版缓存文件
include $cacheFile;
}
/**
* 检查编译缓存是否有效
* @array $template 用到的模板更新时间列表
* @array $templates 用到的模板更新时间列表
* @string $cacheFile 缓存的文件名
* @int $cacheTime 缓存时间
* @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) {
// 缓存是否在有效期
return false;
}
foreach($templates as $time => $path) {
if (is_file($path) && filemtime($path) > $time + $cacheTime) {
// 模板文件如果有更新则缓存需要更新
return false;
}
}
return true;
}
}

View File

@@ -57,43 +57,37 @@ class Sae
* 读取编译编译
* @string $cacheFile 缓存的文件名
* @array $vars 变量数组
* @boolean $isReturn 是否返回内容
* @return void|array
* @return void
*/
public function read($cacheFile, $vars = [], $isReturn = false)
public function read($cacheFile, $vars = [])
{
if (!empty($vars) && is_array($vars)) {
extract($vars, EXTR_OVERWRITE);
}
if ($isReturn) {
return $this->get($cacheFile, 'content');
} else {
eval('?>' . $this->get($cacheFile, 'content'));
}
eval('?>' . $this->get($cacheFile, 'content'));
}
/**
* 检查编译缓存是否有效
* @array $template 用到的模板更新时间列表
* @array $templates 用到的模板更新时间列表
* @string $cacheFile 缓存的文件名
* @int $cacheTime 缓存时间
* @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');
if (0 != $cacheTime && time() > $mtime + $cacheTime) {
// 缓存是否在有效期
return false;
} else {
return true;
}
foreach($templates as $time => $path) {
if (is_file($path) && filemtime($path) > $time + $cacheTime) {
// 模板文件如果有更新则缓存需要更新
return false;
}
}
return true;
}
/**

View File

@@ -35,23 +35,27 @@ class Cx extends Taglib
'switch' => ['attr' => 'name', 'expression' => true],
'case' => ['attr' => 'value,break', 'expression' => true],
'default' => ['attr' => '', 'close' => 0],
'compare' => ['attr' => 'name,value,type', 'alias' => 'eq,equal,notequal,neq,gt,lt,egt,elt,heq,nheq'],
'range' => ['attr' => 'name,value,type', 'alias' => 'in,notin,between,notbetween'],
'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', 'type']],
'empty' => ['attr' => 'name'],
'notempty' => ['attr' => 'name'],
'present' => ['attr' => 'name'],
'notpresent' => ['attr' => 'name'],
'defined' => ['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],
'define' => ['attr' => 'name,value', 'close' => 0],
'for' => ['attr' => 'start,end,name,comparison,step'],
'url' => ['attr' => 'link,vars,suffix,domain', 'close' => 0, 'expression' => true],
'function' => ['attr' => 'name,vars,use,call'],
];
/**
* php标签解析
* 格式:
* {php}echo $name{/php}
* @access public
* @param array $tag 标签属性
* @param string $content 标签内容
@@ -66,10 +70,10 @@ class Cx extends Taglib
/**
* volist标签解析 循环输出数据集
* 格式:
* <volist name="userList" id="user" empty="" >
* {volist name="userList" id="user" empty=""}
* {user.username}
* {user.email}
* </volist>
* {/volist}
* @access public
* @param array $tag 标签属性
* @param string $content 标签内容
@@ -117,6 +121,10 @@ class Cx extends Taglib
/**
* foreach标签解析 循环输出数据集
* 格式:
* {foreach name="userList" id="user" key="key" index="i" mod="2" offset="3" length="5" empty=""}
* {user.username}
* {/foreach}
* @access public
* @param array $tag 标签属性
* @param string $content 标签内容
@@ -192,10 +200,10 @@ class Cx extends Taglib
/**
* if标签解析
* 格式:
* <if condition=" $a eq 1" >
* <elseif condition="$a eq 2" />
* <else />
* </if>
* {if condition=" $a eq 1"}
* {elseif condition="$a eq 2" /}
* {else /}
* {/if}
* 表达式支持 eq neq gt egt lt elt == > >= < <= or and || &&
* @access public
* @param array $tag 标签属性
@@ -211,7 +219,7 @@ class Cx extends Taglib
}
/**
* else标签解析
* elseif标签解析
* 格式见if标签
* @access public
* @param array $tag 标签属性
@@ -228,6 +236,7 @@ class Cx extends Taglib
/**
* else标签解析
* 格式见if标签
* @access public
* @param array $tag 标签属性
* @return string
@@ -241,11 +250,11 @@ class Cx extends Taglib
/**
* switch标签解析
* 格式:
* <switch name="a.name" >
* <case value="1" break="false">1</case>
* <case value="2" >2</case>
* <default />other
* </switch>
* {switch name="a.name"}
* {case value="1" break="false"}1{/case}
* {case value="2" }2{/case}
* {default /}other
* {/switch}
* @access public
* @param array $tag 标签属性
* @param string $content 标签内容
@@ -292,7 +301,7 @@ class Cx extends Taglib
/**
* default标签解析 需要配合switch才有效
* 使用: <default />ddfdf
* 使用: {default /}ddfdf
* @access public
* @param array $tag 标签属性
* @param string $content 标签内容
@@ -307,18 +316,17 @@ class Cx extends Taglib
/**
* compare标签解析
* 用于值的比较 支持 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
* @param array $tag 标签属性
* @param string $content 标签内容
* @param string $type 比较类型
* @return string
*/
public function _compare($tag, $content, $type = 'eq')
public function _compare($tag, $content)
{
$name = $tag['name'];
$value = $tag['value'];
$type = isset($tag['type']) ? $tag['type'] : $type;
$type = isset($tag['type']) ? $tag['type'] : 'eq'; // 比较类型
$name = $this->autoBuildVar($name);
$flag = substr($value, 0, 1);
if ('$' == $flag || ':' == $flag) {
@@ -326,77 +334,34 @@ class Cx extends Taglib
} else {
$value = '\'' . $value . '\'';
}
switch($type) {
case 'equal':
$type = 'eq';
break;
case 'notequal':
$type = 'neq';
break;
}
$type = $this->parseCondition(' ' . $type . ' ');
$parseStr = '<?php if(' . $name . ' ' . $type . ' ' . $value . '): ?>' . $content . '<?php endif; ?>';
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标签解析
* 如果某个变量存在于某个范围 则输出内容 type= in 表示在范围内 否则表示在范围外
* 格式: <range name="var|function" value="val" type='in|notin' >content</range>
* example: <range name="a" value="1,2,3" type='in' >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}
* @access public
* @param array $tag 标签属性
* @param string $content 标签内容
* @param string $type 比较类型
* @return string
*/
public function _range($tag, $content, $type = 'in')
public function _range($tag, $content)
{
$name = $tag['name'];
$value = $tag['value'];
$type = isset($tag['type']) ? $tag['type'] : $type;
$type = isset($tag['type']) ? $tag['type'] : 'in'; // 比较类型
$name = $this->autoBuildVar($name);
$flag = substr($value, 0, 1);
@@ -418,32 +383,10 @@ class Cx extends Taglib
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 name="" >content</present>
* 格式: {present name="" }content{/present}
* @access public
* @param array $tag 标签属性
* @param string $content 标签内容
@@ -460,7 +403,7 @@ class Cx extends Taglib
/**
* notpresent标签解析
* 如果某个变量没有设置,则输出内容
* 格式: <notpresent name="" >content</notpresent>
* 格式: {notpresent name="" }content{/notpresent}
* @access public
* @param array $tag 标签属性
* @param string $content 标签内容
@@ -477,7 +420,7 @@ class Cx extends Taglib
/**
* empty标签解析
* 如果某个变量为empty 则输出内容
* 格式: <empty name="" >content</empty>
* 格式: {empty name="" }content{/empty}
* @access public
* @param array $tag 标签属性
* @param string $content 标签内容
@@ -491,6 +434,15 @@ class Cx extends Taglib
return $parseStr;
}
/**
* notempty标签解析
* 如果某个变量不为empty 则输出内容
* 格式: {notempty name="" }content{/notempty}
* @access public
* @param array $tag 标签属性
* @param string $content 标签内容
* @return string
*/
public function _notempty($tag, $content)
{
$name = $tag['name'];
@@ -501,7 +453,7 @@ class Cx extends Taglib
/**
* 判断是否已经定义了该常量
* <defined name='TXT'>已定义</defined>
* {defined name='TXT'}已定义{/defined}
* @param array $tag
* @param string $content
* @return string
@@ -513,6 +465,13 @@ class Cx extends Taglib
return $parseStr;
}
/**
* 判断是否没有定义了该常量
* {notdefined name='TXT'}已定义{/notdefined}
* @param array $tag
* @param string $content
* @return string
*/
public function _notdefined($tag, $content)
{
$name = $tag['name'];
@@ -521,8 +480,8 @@ class Cx extends Taglib
}
/**
* import 标签解析 <import file="Js.Base" />
* <import file="Css.Base" type="css" />
* import 标签解析 {import file="Js.Base" /}
* 格式:{import file="Css.Base" type="css" /}
* @access public
* @param array $tag 标签属性
* @param string $content 标签内容
@@ -530,9 +489,10 @@ class Cx extends Taglib
* @param string $type 类型
* @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'];
$type = isset($tag['type']) ? strtolower($tag['type']) : ($isFile ? null : 'js');
$parseStr = '';
$endStr = '';
// 判断是否存在加载条件 允许使用函数判断(默认为isset)
@@ -544,8 +504,6 @@ class Cx extends Taglib
$endStr = '<?php endif; ?>';
}
if ($isFile) {
// 根据文件名后缀自动识别
$type = $type ? $type : (!empty($tag['type']) ? strtolower($tag['type']) : null);
// 文件方式导入
$array = explode(',', $file);
foreach ($array as $val) {
@@ -565,8 +523,7 @@ class Cx extends Taglib
}
}
} else {
// 命名空间导入模式 默认是js
$type = $type ? $type : (!empty($tag['type']) ? strtolower($tag['type']) : 'js');
// 命名空间导入模式
$basepath = !empty($tag['basepath']) ? $tag['basepath'] : '/Public';
// 命名空间方式导入外部文件
$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 : '') . '" />';
break;
case 'php':
$parseStr .= '<?php import("' . $val . '"); ?>';
$parseStr .= '<?php \think\Loader::import("' . $val . '"); ?>';
break;
}
}
@@ -598,22 +555,10 @@ class Cx extends Taglib
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 name="" value="" />
* 格式: {assign name="" value="" /}
* @access public
* @param array $tag 标签属性
* @param string $content 标签内容
@@ -635,7 +580,7 @@ class Cx extends Taglib
/**
* define标签解析
* 在模板中定义常量 支持变量赋值
* 格式: <define name="" value="" />
* 格式: {define name="" value="" /}
* @access public
* @param array $tag 标签属性
* @param string $content 标签内容
@@ -656,7 +601,10 @@ class Cx extends Taglib
/**
* for标签解析
* 格式: <for start="" end="" comparison="" step="" name="" />
* 格式:
* {for start="" end="" comparison="" step="" name=""}
* content
* {/for}
* @access public
* @param array $tag 标签属性
* @param string $content 标签内容
@@ -721,4 +669,38 @@ class Cx extends Taglib
$domain = isset($tag['domain']) ? $tag['domain'] : 'false';
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;
}
}