改进变量标签正则表达式;修正volist标签参数判断bug;

This commit is contained in:
oldrind
2016-01-29 22:09:14 +08:00
parent d45e93e5e8
commit d3a7a6207a
4 changed files with 92 additions and 25 deletions

View File

@@ -324,10 +324,8 @@ class Template
*/
private function parsePhp(&$content)
{
if (ini_get('short_open_tag')) {
// 开启短标签的情况要将<?标签用echo方式输出 否则无法正常输出xml标识
$content = preg_replace('/(<\?(?!php|=|$))/i', '<?php echo \'\\1\'; ?>' . "\n", $content);
}
// 短标签的情况要将<?标签用echo方式输出 否则无法正常输出xml标识
$content = preg_replace('/(<\?(?!php|=|$))/i', '<?php echo \'\\1\'; ?>' . "\n", $content);
// PHP语法检查
if ($this->config['tpl_deny_php'] && false !== strpos($content, '<?php')) {
throw new Exception('not allow php tag', 11600);
@@ -855,6 +853,7 @@ class Template
$parseStr = '\\think\\Config::get(\'' . $vars[1] . '\')';
break;
default:
$parseStr = '\'\'';
break;
}
} else {
@@ -967,18 +966,18 @@ class Template
$name = 'name';
}
if ($single) {
$regex = $begin . $tagName . '\b(?>(?:(?!' . $name . '=).)*)\b' . $name . '=([\'\"])(?<name>[\w\/\.\:@,\\\\]+)\\1(?>[^' . $end . ']*)' . $end;
$regex = $begin . $tagName . '\b(?>(?:(?!' . $name . '=).)*)\b' . $name . '=([\'\"])(?<name>[\w\-\/\.\:@,\\\\]+)\\1(?>[^' . $end . ']*)' . $end;
} else {
$regex = $begin . $tagName . '\b(?>(?:(?!' . $name . '=).)*)\b' . $name . '=([\'\"])(?<name>[\w\/\.\:@,\\\\]+)\\1(?>(?:(?!' . $end . ').)*)' . $end;
$regex = $begin . $tagName . '\b(?>(?:(?!' . $name . '=).)*)\b' . $name . '=([\'\"])(?<name>[\w\-\/\.\:@,\\\\]+)\\1(?>(?:(?!' . $end . ').)*)' . $end;
}
break;
case 'tag':
$begin = $this->config['tpl_begin'];
$end = $this->config['tpl_end'];
if (strlen(ltrim($begin, '\\')) == 1 && strlen(ltrim($end, '\\')) == 1) {
$regex = $begin . '((?:(?:[\$]{1,2}|[\:\~][\$a-wA-w_]|[+]{2}[\$]|[-]{2}[\$])[\w\.\:\[\(\*\/\-\+\%_]|\/[\*\/])(?>[^' . $end . ']*))' . $end;
$regex = $begin . '((?:[\$]{1,2}[a-wA-w_]|[\:\~][\$a-wA-w_]|[+]{2}[\$][a-wA-w_]|[-]{2}[\$][a-wA-w_]|\/[\*\/])(?>[^' . $end . ']*))' . $end;
} else {
$regex = $begin . '((?:(?:[\$]{1,2}|[\:\~][\$a-wA-w_]|[+]{2}[\$]|[-]{2}[\$])[\w\.\:\[\(\*\/\-\+\%_]|\/[\*\/])(?>(?:(?!' . $end . ').)*))' . $end;
$regex = $begin . '((?:[\$]{1,2}[a-wA-w_]|[\:\~][\$a-wA-w_]|[+]{2}[\$][a-wA-w_]|[-]{2}[\$][a-wA-w_]|\/[\*\/])(?>(?:(?!' . $end . ').)*))' . $end;
}
break;
}

View File

@@ -81,6 +81,8 @@ class Cx extends Taglib
$empty = isset($tag['empty']) ? $tag['empty'] : '';
$key = !empty($tag['key']) ? $tag['key'] : 'i';
$mod = isset($tag['mod']) ? $tag['mod'] : '2';
$offset = !empty($tag['offset']) && is_numeric($tag['offset']) ? intval($tag['offset']) : 0;
$length = !empty($tag['length']) && is_numeric($tag['length']) ? intval($tag['length']) : 'null';
// 允许使用函数设定数据集 <volist name=":fun('arg')" id="vo">{$vo.name}</volist>
$parseStr = '<?php ';
$flag = substr($name, 0, 1);
@@ -92,10 +94,9 @@ class Cx extends Taglib
$name = $this->autoBuildVar($name);
}
$parseStr .= 'if(is_array(' . $name . ')): $' . $key . ' = 0;';
if (isset($tag['length']) && '' != $tag['length']) {
$parseStr .= ' $__LIST__ = array_slice(' . $name . ',' . $tag['offset'] . ',' . $tag['length'] . ',true);';
} elseif (isset($tag['offset']) && '' != $tag['offset']) {
$parseStr .= ' $__LIST__ = array_slice(' . $name . ',' . $tag['offset'] . ',null,true);';
// 设置了输出数组长度
if (0 != $offset || 'null' != $length) {
$parseStr .= '$__LIST__ = array_slice(' . $name . ',' . $offset . ',' . $length . ', true); ';
} else {
$parseStr .= ' $__LIST__ = ' . $name . ';';
}
@@ -153,7 +154,7 @@ class Cx extends Taglib
if (!isset($var)) {
$var = '$_' . uniqid();
}
$parseStr .= $var . ' = array_slice(' . $name . ',' . $offset . ',' . $length . ',true); ';
$parseStr .= $var . ' = array_slice(' . $name . ',' . $offset . ',' . $length . ', true); ';
} else {
$var = &$name;
}

View File

@@ -55,12 +55,12 @@ EOF;
$this->assertEquals($data, $content);
$content = <<<EOF
{volist name=":explode(',','1,2,3,4,5')" id="vo" key="key" offset="1" length="3"}
{volist name="\$list" id="vo" key="key" offset="1" length="3"}
{\$vo}
{/volist}
EOF;
$template->fetch($content);
$template->fetch($content, ['list' => [1,2,3,4,5]]);
$this->expectOutputString('234');
}
@@ -96,7 +96,7 @@ EOF;
$this->assertEquals($content, $data);
$content = <<<EOF
{foreach name=":explode(',', '1,2,3,4,5')" id="val" key="key" index="index" offset="1" length="3"}
{foreach name=":explode(',', '1,2,3,4,5')" id="val" key="key" index="index" mod="2" offset="1" length="3"}
{\$val}
{/foreach}
EOF;
@@ -313,12 +313,12 @@ EOF;
$cx = new Cx($template);
$content = <<<EOF
{in name="var" value="1,2,3"}
{in name="var" value="\$value"}
default
{/in}
EOF;
$data = <<<EOF
<?php if(in_array((\$var), explode(',',"1,2,3"))): ?>
<?php if(in_array((\$var), is_array(\$value)?\$value:explode(',',\$value))): ?>
default
<?php endif; ?>
EOF;

View File

@@ -104,6 +104,16 @@ EOF;
$template->parse($content);
$this->assertEquals($data, $content);
$content = <<<EOF
{\$name.a|trim==\$name.b?='eq'}
EOF;
$data = <<<EOF
<?php if(trim(\$name['a'])==\$name['b']) echo 'eq'; ?>
EOF;
$template->parse($content);
$this->assertEquals($data, $content);
$content = <<<EOF
{:ltrim(rtrim(\$name.a))}
EOF;
@@ -142,6 +152,14 @@ EOF;
$template->parse($content);
$this->assertEquals($data, $content);
$content = <<<EOF
{\$0a}
EOF;
$data = '{$0a}';
$template->parse($content);
$this->assertEquals($data, $content);
}
public function testVarFunction()
@@ -169,10 +187,12 @@ EOF;
$this->assertEquals($data, $content);
$content = <<<EOF
{\$create_time|trim|substr=0,3}
{\$name}
{\$name|trim|substr=0,3}
EOF;
$data = <<<EOF
<?php echo substr(trim(\$create_time),0,3); ?>
<?php echo \$name; ?>
<?php echo substr(trim(\$name),0,3); ?>
EOF;
$template->parse($content);
@@ -189,7 +209,7 @@ EOF;
$content = <<<EOF
<#\$info.a??'test'#>
EOF;
$data = <<<EOF
$data = <<<EOF
<?php echo (is_array(\$info)?\$info['a']:\$info->a) ? (is_array(\$info)?\$info['a']:\$info->a) : 'test'; ?>
EOF;
@@ -199,7 +219,7 @@ EOF;
$content = <<<EOF
<#\$info.a==\$info.b?='test'#>
EOF;
$data = <<<EOF
$data = <<<EOF
<?php if((is_array(\$info)?\$info['a']:\$info->a)==(is_array(\$info)?\$info['b']:\$info->b)) echo 'test'; ?>
EOF;
@@ -209,11 +229,22 @@ EOF;
$content = <<<EOF
<#\$info.a|default='test'?'yes':'no'#>
EOF;
$data = <<<EOF
$data = <<<EOF
<?php echo ((is_array(\$info)?\$info['a']:\$info->a) !== ''?(is_array(\$info)?\$info['a']:\$info->a):'test')?'yes':'no'; ?>
EOF;
$template->parse($content);
$this->assertEquals($data, $content);
$template2 = new Template();
$template2->tpl_var_identify = 'obj';
$content = <<<EOF
{\$info2.b|trim?'yes':'no'}
EOF;
$data = <<<EOF
<?php echo trim(\$info2->b)?'yes':'no'; ?>
EOF;
$template2->parse($content);
$this->assertEquals($data, $content);
}
public function testTag()
@@ -278,7 +309,8 @@ EOF;
{\$Think.VERSION}<br/>
{\$Think.LDELIM}<br/>
{\$Think.RDELIM}<br/>
{\$Think.SITE_NAME}
{\$Think.SITE_NAME}<br/>
{\$Think.SITE.URL}
EOF;
$data = <<<EOF
<?php echo \$_SERVER['SERVER_NAME']; ?><br/>
@@ -297,9 +329,44 @@ EOF;
<?php echo THINK_VERSION; ?><br/>
<?php echo '{'; ?><br/>
<?php echo '}'; ?><br/>
<?php echo SITE_NAME; ?>
<?php echo SITE_NAME; ?><br/>
<?php echo ''; ?>
EOF;
$template->parse($content);
$this->assertEquals($data, $content);
}
public function testDisplay()
{
$template = new Template();
$template->assign('name', 'name');
$config = [
'strip_space' => true,
'tpl_path' => dirname(__FILE__) . '/',
];
$data = ['name' => 'value'];
$template->display('display', $data, $config);
$this->expectOutputString('value');
}
public function testFetch()
{
$template = new Template();
$template->tpl_path = dirname(__FILE__) . '/';
$data = ['name' => 'value'];
$content = <<<EOF
{\$name}
EOF;
$template->fetch($content, $data);
$this->expectOutputString('value');
}
public function testVarAssign()
{
$template = new Template();
$template->assign('name', 'value');
$value = $template->get('name');
$this->assertEquals('value', $value);
}
}