TinyMCE存库的PHP邮件模板如何执行foreach等逻辑渲染动态数据
解决方案
方案1:使用eval执行模板内PHP代码(仅适用于模板来源100%可控场景)
如果你完全控制模板的编辑权限(仅你自己通过TinyMCE编辑模板,无外部用户可修改数据库内的模板内容),可以通过输出缓冲区+eval执行模板内的PHP逻辑,代码示例:
// 你的业务变量 $name = '收件人姓名'; $response = [ 0 => [ 'name' => 'abc', 'img' => 'linkToImg', 'price'=> '12', 'qty' => 10 ], 1 => [ 'name' => 'xyz', 'img' => 'linkToImg', 'price'=> '15', 'qty' => 2 ], ]; // 读取并解码模板 $content = html_entity_decode($template); // 先替换简单占位符 $content = str_replace('{name}', $name, $content); // 开启输出缓冲区捕获渲染结果 ob_start(); // 执行模板内的混写PHP代码 eval("?> $content <?php "); // 获取最终渲染完成的邮件内容 $finalEmailContent = ob_get_clean();
注意:
eval会执行所有传入字符串中的PHP代码,如果模板可被外部用户修改,绝对不要使用该方案,会导致远程代码执行漏洞。
方案2:使用模板引擎(推荐,安全且适配多模板场景)
如果需要适配多种模板结构、同时规避安全风险,建议使用成熟的PHP模板引擎(比如Twig),将模板内的原生PHP语法替换为模板引擎语法,既能支持任意循环、条件判断等逻辑,也不会有代码执行风险。
实现步骤:
- 安装Twig:执行
composer require twig/twig完成安装 - 修改模板语法:将数据库中模板的原生PHP语法替换为Twig语法,示例如下:
<p style="text-align:center">Hi {{ name }},</p> <p style="text-align:center">This is header</p> <table> <thead> <tr> <th>Name</th> <th>Qty</th> <th>Price</th> </tr> </thead> <tbody> {% for item in response %} <tr> <td><img src="{{ item.img }}" alt="{{ item.name }}" /></td> <td>{{ item.name }}</td> <td>{{ item.qty }}</td> <td>{{ item.price }}</td> </tr> {% endfor %} </tbody> </table>
- 渲染模板的代码示例:
require __DIR__ . '/vendor/autoload.php'; // 初始化Twig加载器,直接从数据库读取的模板内容加载 $loader = new \Twig\Loader\ArrayLoader([ 'email_template' => html_entity_decode($template), ]); $twig = new \Twig\Environment($loader); // 传入所有变量直接渲染得到最终邮件内容 $finalEmailContent = $twig->render('email_template', [ 'name' => $name, 'response' => $response ]);
该方案支持任意模板结构(表格、列表、自定义排版等),会自动处理输出转义避免XSS风险,完全适配多场景多模板的需求。
内容的提问来源于stack exchange,提问作者Muhammad Hashir Anwaar
相关产品推荐
相关产品推荐

