优化数组中的字符串替换

时间:2012-07-29 10:16:41

标签: php string optimization loops

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

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是最好的。

1 个答案:

答案 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,那么你需要一个命名函数。)