2011-09-05 54 views
1

我正在写一个邮件类,它将内容存储在数据库中并将其加载到模板中,然后将其作为HTML电子邮件发送。但是,由于每封电子邮件都包含PHP变量和动态内容,因此我决定使用分隔符。因此,而不是内容看起来像:用PHP变量替换分隔符

Hello $username, welcome to the site. 

它会看起来像:

Hello {{username}}, welcome to the site. 

到目前为止我用这些方法:

function load($name,$content) 
{ 
    // preps the template for HTML 
} 

function content($template_id) 
{ 
    $template = $this->db->get_where('email_templates',array('id'=>$template_id)); 
    return $template->content; 
} 

function new_email($email,$name,$user_type) 
{ 
    $msg = $this->load($name,$this->content(1)); 
    $this->send($email,'Thanks for your application',$msg,1); 
} 

我有麻烦是如何将{{variable}}转换为$变量以便解析 - 我不希望它仅仅作为$ username加载到电子邮件模板中。它只是使用正则表达式并转义字符串以便解析的情况吗?类似于:

$content = str_replace("{{","'.$",$template->content); 
$content = str_replace("}}",".'",$template->content); 

或者这是否有缺陷?有人知道什么是最好的做法吗?

+0

对此使用正则表达式。如果你以后想要实现任何类型的逻辑(循环或嵌套的条件),那么让我在那里阻止你。使用现有的实现。存在轻量级模板引擎,并且231个类中的一个将肯定支持您所需的双重卷曲语法。 – mario

回答

3

我不会创建自己的模板系统,因为那里有现成的模板系统。

最受欢迎的可能是Smarty,但还有另一个与您创建的格式相同,即mustache

更新:

与您的代码的问题是,你要替换的{{.$并存储在$content变量,然后更换}}.和覆盖该更换$content变量。

一种可能有效的解决方案可能是:

if (preg_match_all("/{{(.*?)}}/", $template, $m)) { 
    foreach ($m[1] as $i => $varname) { 
    $template = str_replace($m[0][$i], sprintf('$%s', $varname), $template); 
    } 
} 

但你还需要以某种方式eval你的代码。

+0

我知道Smarty - 但我只想实现这个单一类的功能。安装和配置整个模板引擎似乎有点繁重...... – hohner

+0

这取决于。您将拥有许多带* fast *模板系统的功能。 –

+3

我会建议Twig,http://twig.sensiolabs.org/ – Aknosis

0

使用preg_replace_callback,请参阅:http://codepad.org/EvzwTqzJ

<?php 

$myTemplateStr = "Hello {{username}} , this is {{subject}} ,and other string {{example}}"; 
$tagRegex = "|{{(.*?)}}|is"; 
$result = preg_replace_callback($tagRegex,"myReplaceFunc",$myTemplateStr); 
echo $result ; 

/* output :  

Hello $username , this is $subject ,and other string {{example}} 

*/ 



function myReplaceFunc($matches) 
{ 
    $validTags = array('username','subject','name'); 
    $theFull = $matches[0]; 
    $theTag = $matches[1]; 
    if(in_array($theTag,$validTags) == true) 
    return '$'.$theTag; 
    return $theFull ; 
} 

?> 
0

如果你要自己做它可能是最好只是用明确str_replace函数。如果您尝试将卷曲护腕转换为$,则需要​​eval(),这是一个潜在的安全漏洞。

这将是我的方法与str_replace - 这变得难以维护,因为你添加更多的变量,但它并没有变得更简单。

$content = str_replace(
      array('{{username}}','{{var2}}'), 
      array($username,$var2), 
      $template->content 
      ); 
2

在电子邮件模板变换{{variable}}$variable后,所以,您将使用eval得到它取代该变量的实际内容是什么?

为什么不直接用$variable的内容替换{{variable}}

也许有一个函数需要模板文本和一个placeholder => "text to replace it with"的数组。然后,通过在该阵列的关键字周围添加{{}}并做str_replace,就像制作占位符的精确字符串一样简单。

foreach ($replacements as $placeholder => $value) { 
    $placeholder = "{{" . $placeholder . "}}" ; 
    $text = str_replace($placeholder, $value, $text) ; 
} 

将此与(类)常量用于占位符,并且您有一个非常稳定且打字错误的模板系统。它不会像使用完整的模板解决方案那样优雅或易于使用,并且可能需要编写使用它的代码的人进行额外的工作,但是由于命名错误的变量,他们在开发期间不会犯错误。