有人能帮我弄清楚为什么while循环中的str_replace只替换电子邮件模板中的第一行吗?
以下是守则:
$vehicle=mysql_query("select * from tbl_vehicle where book_id='$booking_Id'");
$i=0;
while($rows=mysql_fetch_array($vehicle)){
$make = $rows['make'];
$model = $rows['model'];
$message = str_replace("[make]",$make,$message);
$message = str_replace("[model]",$model,$message);
$i++;}
和html模板;
<tr>
<td>Car Make</td>
<td>[make]</td>
</tr>
<tr>
<td>Car Model</td>
<td>[model]</td>
我正在从数据库中获取模板。
问题是,当一辆车被预订时,它可以正常工作,但如果多一辆车被预订,它只会在电子邮件中替换第一辆车的详细信息。
谢谢你的帮助。
编辑;例如,如果有一辆车预订,它将在电子邮件模板中显示
制造:制造-1
型号:模型一
如果预定了2辆车,电子邮件模板显示
制造:制造-1
型号:模型一
但它应该表明
制造:制造-1
型号:模型一
制造:制造-2
型号:型号2
希望这能澄清问题。
更新;Simon_w解决方案没有工作,但给了我一个想法(我不知道它的最佳方法或不)
while($rows=mysql_fetch_array($vehicle)){
$make = $rows['make'];
$model = $rows['model'];
$i++;
if($i==2) {
$message = str_replace("[make]",$make,$message);
$message = str_replace("[model]",$model,$message);
$message = str_replace("[make2]",$make,$message);
$message = str_replace("[model2]",$model,$message);
}
else {
$message = str_replace("[make]",$make,$message);
$message = str_replace("[model]",$model,$message);
}
}
在电子邮件模板中
<tr>
<td>Car Make</td>
<td>[make]</td>
</tr>
<tr>
<td>Car Model</td>
<td>[model]</td>
<tr>
<td>Car Make</td>
<td>[make2]</td>
</tr>
<tr>
<td>Car Model</td>
<td>[model2]</td>
因此,这解决了2辆车的问题,两者都详细显示,但如果只有一辆车预订,然后在电子邮件模板make2显示空白,所以有任何方法使用if语句在电子邮件模板?
发布于 2014-11-30 20:23:38
这是因为您正在更改$message
的值。您可以在while
循环开始时重新加载它,或者将它存储到一个单独的变量中,这样它就不会被覆盖。例如,您可以使用$body
而不是$message
,这意味着$message
的内容永远不会改变。
编辑:编辑到原来的问题,我已经改变了代码,以建立电子邮件的主体,在每个循环的模板附加到它。
$body = '';
while($rows=mysql_fetch_array($vehicle)){
$make = $rows['make'];
$model = $rows['model'];
$body .= str_replace(array("[make]", "[model]"),array($make,$model),$message);
$i++;
}
发布于 2014-11-30 21:13:55
str_replace()
将替换字符串中的所有事件(即所有占位符),这意味着当您访问第二个DB记录时,就没有需要替换的占位符了。来自 manual
此函数返回一个字符串或数组,其主题中出现的所有搜索都替换为给定的替换值。
您可以使用限制为1的preg_replace()
:
$i = 0;
foreach ($example_db_results as $rows) {
$make = $rows['make'];
$model = $rows['model'];
$message = preg_replace("/\[make\]/", $make, $message, 1);
$message = preg_replace("/\[model\]/", $model, $message, 1);
$i++;
}
这里的例子:https://eval.in/228673
编辑:听你的评论-听起来像是数据不一致.您的模板有固定的行数,但是您的数据库可以有很多行。您应该为每个循环接受模板,并添加一个外部HTML变量,这样HTML行数和数据库行数是相等的。
在这种情况下,您不需要限制替换,因为其中只有一个,所以我将向您展示一个示例,说明您最初的尝试:
$i = 0;
$output = '';
foreach ($example_db_results as $rows) {
$make = $rows['make'];
$model = $rows['model'];
// Define your temporary template variable
$temp_template = $template;
$temp_template = str_replace("[make]", $make, $temp_template);
$temp_template = str_replace("[model]", $model, $temp_template);
// Append the temp template to the output variable
$output .= $temp_template;
unset($temp_template);
$i++;
}
正如@r3wt在他对您的问题的评论中所提到的,在这样做时,您可以(而且应该)将数组传递到str_replace()
。如果占位符的数量会增加,那将是个好主意。
这里的例子:https://eval.in/228714
发布于 2014-11-30 20:24:28
您应该使用正则表达式来获得更好的结果。
示例:
$template = //email template
$wrapper = '/\[+(.*?)\]/';
$matches = array();
preg_match_all($wrapper, $template, $matches);
更新:对误解表示歉意。我碰巧有一个肮脏的课,这正是OP要求的!唯一的区别是我使用[{()}]
包装,对可能包含多个值的元素使用[<loop>] [</loop>]
。
给你;)
class StringTemplate{
protected $template;
protected $tokens;
protected $wrapper;
protected $loopTag;
protected $widgets;
protected $widgetWrapper;
protected $loopBlock;
protected $tokenMissed;
protected $loopTemplate;
protected $data;
public function __construct($template)
{
$this->data = array();
$this->tokens = array();
$this->wrapper = '/\[\{\(+(.*?)\)\}\]/';
$this->widgetWrapper = '/\[\{\(widget:+(.*?)\)\}\]/';
$this->loopTag = 'loop';
$this->loopWrapper = '/\[\<'.$this->loopTag.'\>\]+(.*?)\[\<\/'.$this->loopTag.'\>\]/s';
$this->template = $template;
if (preg_match($this->loopWrapper, $this->template, $matches)){
$this->loopBlock = $matches[1];
$this->loopTemplate = $matches[0]; // includes [<loop>]
}
if (preg_match_all($this->wrapper, $this->template, $matches)){
$tokens = $matches[1];
foreach ($tokens as $token){
if (strpos($token, ':')){
$tokenDetails = explode(':', $token);
$this->tokens[$tokenDetails[0]][] = $tokenDetails[1];
} else {
$this->tokens[] = $token;
}
}
}
}
public function setData($data){
$offsets = array();
$missedToken = false;
/* loop available */
if ($this->loopTemplate){
if (!isset($data[$this->loopTag][0])){
$missedToken = true;
} else {
$offsets = array_merge(array_keys($data), array_keys($data[$this->loopTag][0]));
}
} else {
$offsets = array_keys($data);
}
foreach ($this->tokens as $key=>$token){
if (is_array($token)){
foreach ($token as $value){
if (!isset($data[$key.':'.$value])){
$this->tokenMissed[$key][] = $value;
}
}
} else if (!isset($data[$token])){
$this->tokenMissed[] = $token;
}
}
if (!$this->tokenMissed){
// Loop first..
$loopOutput = null;
$output = $this->template;
if (isset($data[$this->loopTag])){
foreach ($data[$this->loopTag] as $loop){
$loopOutput .= $this->wrapData($this->loopBlock,array_merge($data,$loop));
}
$output = str_replace($this->loopTemplate, $loopOutput, $this->template);
}
$output = $this->wrapData($output,$data);
return $output;
}
//print_r('<pre>');
//print_r($data);
//print_r($output);
//print_r($this->tokenMissed);
//print_r($offsets);
//print_r($this->tokens);
//print_r($this->loopTemplate);
//print_r(array_diff($this->tokens, $offsets));
//print_r($this->template);
//print_r('</pre>');
//die;
}
public function wrapData($template,$data) {
$output = $template;
if (preg_match_all($this->wrapper, $template, $matches)){
$tokens = $matches[1];
$wrappers = $matches[0];
$values = array();
foreach ($tokens as $token){
if (isset($data[$token])){
$values[] = $data[$token];
}
}
$output = str_replace($wrappers, $values, $template);
}
return $output;
}
public function getTokens()
{
return $this->tokens;
}
public function getMissedTokens()
{
return $this->tokenMissed;
}
}
https://stackoverflow.com/questions/27217792
复制相似问题