You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

数据库中用str_replace替换短码为PHP代码时仅显示源码问题排查

解决邮件模板短码显示PHP代码而非执行结果的问题

嘿,我来帮你理清这个问题!你现在遇到的核心问题是:你的代码只是把数据库里的PHP代码字符串替换到邮件内容里,但PHP并不会自动执行这些嵌入的字符串代码,所以最终邮件里显示的是原始的PHP代码文本,而不是代码运行后的结果。

问题根源拆解

你用str_replace做的只是纯字符串替换:把[order_date]替换成了date("l jS F Y", strtotime($OrderDate))这个文本串,但PHP不会主动去解析执行这个字符串里的代码逻辑,自然就会直接把这段代码原样显示在邮件里了。

解决方案

下面给你两种可行的解决思路,分别对应直接执行代码(需注意安全)和更安全的短码映射方案:

方案1:执行替换后的PHP代码(快速但有安全风险)

如果一定要保留数据库存PHP代码的方式,你可以用eval来执行这段代码,同时用输出缓冲捕获执行结果:

// Make template substitutions
$sqlsub = "SELECT * FROM templates_subs";
$setsub = $link->query($sqlsub);
while($rowsub = $setsub->fetch_array(MYSQLI_ASSOC)) {
    $replacementCode = $rowsub['SubReplacement'];
    // 开启输出缓冲,捕获代码执行的输出
    ob_start();
    // 执行代码并输出结果到缓冲
    eval("echo $replacementCode;");
    // 获取缓冲里的执行结果
    $actualReplacement = ob_get_clean();
    // 替换模板中的短码
    $MessageBody = str_replace($rowsub['SubOriginal'], $actualReplacement, $MessageBody);
}

⚠️ 重要安全提醒:eval是非常危险的函数,如果数据库里的SubReplacement字段被注入了恶意代码(比如被攻击者篡改),eval会直接执行这些恶意代码,可能导致服务器被入侵。所以使用这个方案的前提是:只有绝对可信的人员能修改templates_subs表的内容,绝对不能让用户提交的内容进入这个字段。

方案2:短码映射(更安全、易维护)

更推荐的做法是不在数据库里存原始PHP代码,而是存短码对应的标识,然后在代码里统一处理逻辑。这种方式完全避免了eval的安全风险,也更便于维护:

  1. 先修改数据库的SubReplacement字段:比如把date("l jS F Y", strtotime($OrderDate))改成order_date(一个简洁的标识)。
  2. 在代码里定义短码对应的处理逻辑:
// Set fields (StackOverflow example - data from a previous db query)
$OrderDate = $row['OrderDate'];
$CustomerName = $row['CustomerName']; // 假设你还有其他变量

// 定义短码与处理逻辑的映射
$shortcodeMap = [
    'order_date' => function() use ($OrderDate) {
        return date("l jS F Y", strtotime($OrderDate));
    },
    // 可以轻松添加更多短码
    'customer_name' => function() use ($CustomerName) {
        // 用htmlspecialchars防止XSS风险
        return htmlspecialchars($CustomerName);
    }
];

// Get customer order confirmation template
$sql = "SELECT DeliveryTemplateSubject, DeliveryTemplateContent FROM delivery_templates WHERE DeliveryTemplateTemplate='1'";
$set = $link->query($sql);
$row = $set->fetch_row();
$MessageBody = nl2br($row[1]);

// Make template substitutions
$sqlsub = "SELECT * FROM templates_subs";
$setsub = $link->query($sqlsub);
while($rowsub = $setsub->fetch_array(MYSQLI_ASSOC)) {
    $shortcodeKey = $rowsub['SubReplacement'];
    // 如果存在对应的处理逻辑,就执行并替换
    if (isset($shortcodeMap[$shortcodeKey])) {
        $actualReplacement = $shortcodeMap[$shortcodeKey]();
        $MessageBody = str_replace($rowsub['SubOriginal'], $actualReplacement, $MessageBody);
    }
}

// Email customer
$subject = $row[0];
mail($CustomerEmail, $subject, $MessageBody);

这种方式的优势在于:所有的执行逻辑都在你的代码控制范围内,数据库里只是存标识,不会有恶意代码执行的风险;后续要修改短码的处理逻辑或者添加新短码,直接修改$shortcodeMap数组即可,非常清晰。

内容的提问来源于stack exchange,提问作者Stuart Pinfold

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:19:18