0

我有一个包含一组模板的表。这些模板有占位符,需要在运行时替换给定键值对数组。这是我进行替换的代码:

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是可以做到的最好的。

4

1 回答 1

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,则需要一个命名函数。)

于 2012-07-29T10:42:44.857 回答