
使用 `file_get_contents()` 直接读取含 php 代码的模板文件会导致源码暴露;应改用输出缓冲(output buffering)配合 `include`,让 php 解析并执行模板中的逻辑,最终获取渲染后的 html 内容。
在 PHPMailer 中动态加载邮件模板时,若模板文件(如 template.php)包含 PHP 代码(例如变量输出、条件判断或循环),直接用 file_get_contents() 读取会将其作为纯文本返回——PHP 标签 及其内容不会被解析,而是原样出现在邮件正文中,造成安全风险与功能失效。
✅ 正确做法:使用输出缓冲 + include
include 会实际执行 PHP 文件中的代码,而 ob_start() / ob_get_clean() 能捕获其输出结果(即执行后生成的 HTML),而非源码本身。修改 mail.php 中模板加载部分如下:
$template_file = 'PHPMailer/template.php';
if (!file_exists($template_file)) {
die("Unable to locate the template file");
}
// 启动输出缓冲,引入并执行模板文件,捕获执行结果
ob_start();
include $template_file;
$mail_template = ob_get_clean();
// ✅ $mail_template 现在是执行后的 HTML 字符串(如 "Some words here"),不含任何 PHP 标签⚠️ 注意事项:
-
不要对 include 结果做 htmlspecialchars():你之前调用 htmlspecialchars(file_get_contents(...)) 是为防止 XSS,但此处已执行 PHP 并获取纯净 HTML 输出,再转义会破坏 HTML 结构(如
变成 zuojiankuohaophpcnpyoujiankuohaophpcn),导致邮件显示为源码文本。
- 确保模板中无未定义变量或运行时错误:include 在当前作用域执行,因此 $forexample 等变量需在 include 前已声明,或在模板内自行初始化。建议在模板顶部添加 access'); ?> 提升安全性。
- 避免敏感逻辑外泄:模板文件不应包含数据库密码、API 密钥等,仅保留视图层逻辑(如格式化、简单循环、本地变量插值)。
? 进阶建议:
可封装为可复用函数,支持传参(如 $data = ['name' => 'Alice']),并在模板中通过 extract($data) 使用:
function renderTemplate($file, $data = []) {
if (!file_exists($file)) return '';
extract($data); // 将数组键转为变量
ob_start();
include $file;
return ob_get_clean();
}
// 使用:$mail_template = renderTemplate('PHPMailer/template.php', ['username' => 'John']);这样既保障了 PHP 逻辑正常执行,又保持了模板的灵活性与安全性。
立即学习“PHP免费学习笔记(深入)”;











