我有一个包含一组模板的表。这些模板具有占位符,在给定键值对数组的情况下,需要在运行时替换这些占位符。这是我的替换代码:
function replace_placeholders(&$input_values) {
$result = execute_pdo_query("SELECT name,value FROM templates");
foreach($result as $currow) {
$varname = $currow[name];
$varvalue = $currow['value'];
foreach($input_values as $key => $value) {
$key = '{'.strtolower($key).'}';
$varvalue = str_replace($key,trim($value),$varvalue);
}
$input_values[$varname] = $varvalue;
}
}
问题在于存在大量模板和许多键值对。因此,这个嵌套循环会被执行很多次,占用差不多半秒。有没有办法优化这种替代品?我已经搜索了一个优化,但主要是说str_replace
是最好的。
答案 0 :(得分:1)
您没有向我们展示$input_values
包含的内容,但我认为这是要替换的所有可能标记的全局列表。
在这种情况下,一个明显的弱点是你为每个模板循环这个。如果模板中恰好只有一个标签,那就太浪费了。
我很想尝试更改它,以便您可以通过preg_replace_callback
仅对模板中提到的标记执行操作,而不是遍历每个模板的所有可能标记。我无法保证这会更快,但这是我第一次尝试。
这是一个简化的例子:
$transformations = array(
'name' => 'John',
'pronoun' => 'you'
'animal' => 'dog'
'building' => 'house'
'food' => 'chocolate'
'friend' => 'Kelvin'
/* etc, potentially many more */
);
$template = "hello, {name}, how are {pronoun}?";
$transformed_template = preg_replace_callback('/\{(\w*)\}/', function($match) {
global $transformations;
if (isset($transformations[$match[1]]))
return trim($transformations[$match[1]]);
}, $template);
模板只包含两个占位符,我们只对这些占位符执行操作,而不是遍历$transformations
中所有可能的标记替换。
(注意我使用匿名函数作为preg_replace_callback()
的回调。如果你使用的是PHP< 5.3,那么你需要一个命名函数。)