首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >带有邮件功能的php循环中的str_replace函数

带有邮件功能的php循环中的str_replace函数
EN

Stack Overflow用户
提问于 2014-11-30 20:19:53
回答 3查看 1.1K关注 0票数 0

有人能帮我弄清楚为什么while循环中的str_replace只替换电子邮件模板中的第一行吗?

以下是守则:

代码语言:javascript
运行
复制
$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模板;

代码语言:javascript
运行
复制
<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解决方案没有工作,但给了我一个想法(我不知道它的最佳方法或不)

代码语言:javascript
运行
复制
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);
    }
}

在电子邮件模板中

代码语言:javascript
运行
复制
<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语句在电子邮件模板?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-11-30 20:23:38

这是因为您正在更改$message的值。您可以在while循环开始时重新加载它,或者将它存储到一个单独的变量中,这样它就不会被覆盖。例如,您可以使用$body而不是$message,这意味着$message的内容永远不会改变。

编辑:编辑到原来的问题,我已经改变了代码,以建立电子邮件的主体,在每个循环的模板附加到它。

代码语言:javascript
运行
复制
$body = '';
while($rows=mysql_fetch_array($vehicle)){
    $make = $rows['make'];
    $model = $rows['model'];
    $body .= str_replace(array("[make]", "[model]"),array($make,$model),$message);
    $i++;
}
票数 2
EN

Stack Overflow用户

发布于 2014-11-30 21:13:55

str_replace()将替换字符串中的所有事件(即所有占位符),这意味着当您访问第二个DB记录时,就没有需要替换的占位符了。来自 manual

此函数返回一个字符串或数组,其主题中出现的所有搜索都替换为给定的替换值。

您可以使用限制为1的preg_replace()

代码语言:javascript
运行
复制
$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行数和数据库行数是相等的。

在这种情况下,您不需要限制替换,因为其中只有一个,所以我将向您展示一个示例,说明您最初的尝试:

代码语言:javascript
运行
复制
$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

票数 1
EN

Stack Overflow用户

发布于 2014-11-30 20:24:28

您应该使用正则表达式来获得更好的结果。

示例:

代码语言:javascript
运行
复制
$template = //email template
$wrapper  = '/\[+(.*?)\]/';
$matches  = array();
preg_match_all($wrapper, $template, $matches);

更新:对误解表示歉意。我碰巧有一个肮脏的课,这正是OP要求的!唯一的区别是我使用[{()}]包装,对可能包含多个值的元素使用[<loop>] [</loop>]

给你;)

代码语言:javascript
运行
复制
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;  
    } 


}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27217792

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档