str_replace()可实现最轻量模板填充,但需统一占位符格式、分离模板与数据、过滤用户输入防xss,并注意邮件客户端兼容性及编码问题。

用 str_replace() 做最轻量的模板填充
不需要引入 Twig 或 Blade,PHP 原生就能搞定基础邮件模板。核心就是把占位符(比如 {name}、{order_id})替换成真实值。str_replace() 比 preg_replace() 更快、更安全,也更可控。
常见错误是直接拼接 HTML 字符串,导致后期维护困难、易 XSS(尤其用户输入没过滤时)。模板字符串应和数据分离。
- 模板内容建议存在独立文件(如
email_welcome.tpl),用file_get_contents()读取,避免硬编码 - 占位符统一用大括号包裹,如
{user_name},避免和 PHP 变量语法冲突 - 替换前对用户数据做基础过滤:
htmlspecialchars($value, ENT_QUOTES, 'UTF-8'),防止 HTML 注入 - 如果占位符数量多,用两个数组传给
str_replace():第一个是键数组(['{name}', '{email}']),第二个是值数组([$name, $email])
用 extract() + include 实现变量直写式模板
如果你希望模板里直接写 <p>您好,=$name?></p>,可以用 PHP 原生的变量导入机制。这不是“模板引擎”,但足够简单项目使用。
注意:必须严格控制传入 extract() 的数据来源,禁止把 $_POST 或未清洗的数组直接丢进去,否则可能覆盖关键变量(如 $template、$content)。
- 模板文件后缀建议用
.php(如email_reset.php),但不要被 Web 服务器直接访问,放非 webroot 目录下 - 先
ob_start(),再extract($data),然后include模板文件,最后ob_get_clean()拿到渲染结果 - 模板内所有输出都应经过
htmlspecialchars(),例如=$name ?? ''?>改成=htmlspecialchars($name ?? '', ENT_QUOTES, 'UTF-8')?> - 不推荐在模板中写逻辑(如
if、foreach),一旦有循环或条件,就该换真模板引擎了
发信前检查 mail() 的返回值和常见失败点
mail() 返回 true 只代表“交给本地 MTA 了”,不代表邮件真的发出去了。很多问题出在配置或权限上,而不是模板本身。
典型现象:本地开发环境能发,上线后收不到;或收到邮件但样式错乱、中文变问号。
- 确保
Content-Type头含charset=UTF-8,例如:"Content-Type: text/html; charset=UTF-8" - 中文主题要用
mb_encode_mimeheader()编码,否则 Outlook 等客户端显示乱码:mb_encode_mimeheader('欢迎注册', 'UTF-8', 'B') - Linux 服务器若没装
sendmail或postfix,mail()会静默失败;可用which sendmail检查 - 部分虚拟主机禁用
mail(),此时必须改用 SMTP(如 PHPMailer 或SwiftMailer),不能硬扛
模板里带 CSS 样式怎么保证兼容性
HTML 邮件不是网页,大部分客户端(尤其是 Outlook)只支持内联样式,且不识别 <style></style> 标签或外部 CSS。
别指望用 Tailwind 或 Bootstrap 类名——它们在邮件里基本无效。最稳妥的方式是手写内联 style 属性,或用工具做「CSS inlining」。
- 简单项目:直接在标签里写
style="color:#333; font-size:14px;",避免 class 和 style 分离 - 如果已有 CSS 文件,可用开源库如
pelago/emogrifier把样式提取并内联(注意它不处理伪类和复杂选择器) - 表格布局仍是邮件兼容性之王:
<table> 套 <code><tr><td> 比 <code>flex或grid稳定得多 - 字体尽量用安全字体栈:
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif,避免自定义 Web Font
模板功能越简单,越容易漏掉字符编码、XSS 过滤、MIME 头设置这些细节。它们不体现在“能不能渲染”,而体现在“收件人看到什么”。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











