2012-07-29 32 views
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是可以完成的最好的。

回答

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

+0

完美的作品。接受,+1。 – recluze 2012-08-10 13:27:38