9

我有一个电子邮件系统,用户在其中写一条消息,它会发送消息。我刚刚发现的主要问题,考虑这段代码

    $findEmail = $this->Data->field('body', array('id' => 1610));

    //$getUserEmailTemplate will take frm dbase and e.g: 
    //Hi, @@MESSAGE@@. From: StackOverflow
    //It should change @@MESSAGE@@ part to data from $findEmail (in this example is the $74.97 ...)

    $getUserEmailTemplate = $findUser['User']['email_template'];
    $emailMessage = preg_replace('/\B@@MESSAGE@@\B/u', $findEmail, $getUserEmailTemplate);

    debug($findEmail);
    debug($emailMessage);

并考虑 $findemail 结果的电子邮件的此输入:

$74.97
$735.00s

$email 消息将导致:

.97
5.00s

我怎样才能解决这个问题?我觉得我的 preg_replace 模式有问题。

用户模板可以是任何东西,只要其中有@@MESSAGE@@,那部分就会改成用户消息输入。

谢谢

4

5 回答 5

13

预解析替换文本以转义$when 后跟一个数字(请记住,$n在替换文本中使用时具有特殊含义)。请参阅php.net 文档页面上的评论:

如果您的替换文本有可能包含任何字符串,例如“$0.95”,您需要转义这些 $n 反向引用:

<?php
  function escape_backreference($x){
    return preg_replace('/\$(\d)/', '\\\$$1', $x);
  }
?>
于 2013-09-24T23:50:10.533 回答
3

高票函数escape_backreference在一般情况下是不完整的:它只会逃避形式的反向引用$n,而不是形式${n}或的反向引用\n

要逃避任何潜在的反向引用,请更改

    $emailMessage = preg_replace('/\B@@MESSAGE@@\B/u', $findEmail, $getUserEmailTemplate);

    $emailMessage = preg_replace('/\B@@MESSAGE@@\B/u', addcslashes($findEmail, '\\$'), $getUserEmailTemplate);
于 2020-04-22T14:17:48.707 回答
1

原因如下:

替换文本的$1部分代表找到的第一个组/匹配项。因此,如果您有abc 123并且尝试过preg_match('/([\w]+)-([\d]+)/'),正则表达式将在内部存储类似$1 = abcand的内容$2 = 123。这些变量将存在,即使它们没有价值。

因此,例如:

$text = '[shortcode]';
$replacement = ' some $var $101 text';
$result = preg_replace('/\[shortcode\]/', $var, $text);
// returns "some $var 1 text"

由于匹配组$10为空,因此将替换为空字符串。

这就是为什么您需要在运行该函数$NN之前从您的 REPLACEMENT 文本中转义任何内容。preg_replace

快乐编码。

于 2018-01-12T11:51:39.967 回答
0

如果(曾经)有一个模板存在$getUserEmailTemplate,那么您确实用这一行覆盖(销毁)它;

$getUserEmailTemplate = "@@MESSAGE@@";

因此,只需删除此行并确保$getUserEmailTemplate确实包含任何内容,并且最好是一个模板。

于 2013-09-25T00:09:58.097 回答
-1

猜猜您的模板只包含“纯”PHP 并尝试使用 $74 作为变量,该变量不存在且不包含任何数据。所以将模板中的引号改为单引号'

猜测模板:

$tpl = "Sum: $74.97"; //results in "Sum: .97"

更正的模板:

$tpl = 'Sum: $74.97'; //results in "Sum: $74.97"
于 2013-09-24T23:49:10.163 回答