我有一个模板式系统,可以加载批量模板(一个文件中有多个模板条目)并相应地存储它们。问题是当前的方法使用preg_replace()
和eval
,而且它确实容易出错。此错误的一个示例可能是放置不正确的字符,该字符会破坏正则表达式并创建解析错误:
Parse error: syntax error, unexpected '<' in tsys.php: eval()'d code
执行此操作的代码表示加载如下:
// Escaping
$this->_buffer = str_replace( array('\\', '\'', "\n"), array('\\\\', '\\\'', ''), $this->_buffer);
// Regular-expression chunk up the input string to evaluative code
$this->_buffer = preg_replace('#<!--- BEGIN (.*?) -->(.*?)<!--- END (.*?) -->#', "\n" . '$this->_tstack[\'\\1\'] = \'\\2\';', $this->_buffer);
// Run the previously created PHP code
eval($this->_buffer);
此批量模板的示例文件如下所示:
<!--- BEGIN foo -->
<p>Some HTML code</p>
<!--- END foo -->
<!--- BEGIN bar -->
<h1>Some other HTML code</h1>
<!--- END bar -->
当在此输入上运行代码时,$this->_tstack
将被赋予两个元素:
array (
'foo' => "<p>Some HTML code</p>",
'bar' => "<h1>Some other HTML code</h1>",
);
这是预期的行为,但我正在寻找一种方法,我们可以放弃eval
的需要。
答案 0 :(得分:1)
您可以使用preg_match_all
来执行此操作:
// Remove CR and NL
$buffer = str_replace(array("\r", "\n"), '', $this->_buffer);
// Grab interesting parts
$matches = array();
preg_match_all('/\?\?\? BOT (?P<group>[^ ]+) \?\?\?(?P<content>.*)!!! EOT \1 !!!/', $buffer, $matches);
// Build the stack
$stack = array_combine(array_values($matches['group']), array_values($matches['content']));
将输出:
Array
(
[foo] => <p>Some HTML code</p>
[bar] => <h1>Some other HTML code</h1>
)
答案 1 :(得分:1)
嗯,这就是。鉴于$template
包含:
<!--- BEGIN foo -->
<p>Some HTML code</p>
<!--- END foo -->
<!--- BEGIN bar -->
<h1>Some other HTML code</h1>
<!--- END bar -->
然后:
$values = array();
$pattern = '#<!--- BEGIN (?P<key>\S+) -->(?P<value>.+?)<!--- END (?P=key) -->#si';
if ( preg_match_all($pattern, $template, $matches, PREG_SET_ORDER) ) {
foreach ($matches as $match) {
$values[$match['key']] = trim($match['value']);
}
}
var_dump($values);
结果:
array(2) {
["foo"]=>
string(21) "<p>Some HTML code</p>"
["bar"]=>
string(29) "<h1>Some other HTML code</h1>"
}
如果保留空白区很重要,请删除trim()
。