news 2026/9/14 18:29:56

PHPMailer 的 mail、sendmail 与 SMTP 三种发送方式怎么选?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
PHPMailer 的 mail、sendmail 与 SMTP 三种发送方式怎么选?

PHPMailer 的 mail、sendmail 与 SMTP 三种发送方式怎么选?

【免费下载链接】PHPMailerThe classic email sending library for PHP项目地址: https://gitcode.com/GitHub_Trending/ph/PHPMailer

PHPMailer 支持三种邮件传输方式:调用 PHP 内置的mail()函数、直接执行本机的 sendmail 程序、以及通过内置 SMTP 客户端连接 SMTP 服务器。三种方式写邮件内容的代码几乎一样,差别只在“如何把消息交给传输系统”。如果你正在 PHP 项目里集成 PHPMailer,需要在动手前确定用哪一种,这篇文章基于仓库内的examples/示例和 README,给出三种方式各自的前提条件、官方示例代码和验证方式,帮你按运行环境做出选择。

适用前提:PHP 5.5 及以上(README 说明兼容至 PHP 8.2),推荐通过 Composer 安装。当前仓库版本号为 6.9.3(见 VERSION)。

先安装 PHPMailer

无论选哪种传输方式,加载方式相同。README 推荐用 Composer 安装:

composer require phpmailer/phpmailer

或把"phpmailer/phpmailer": "^6.9.2"加入composer.json。注意vendor目录和vendor/autoload.php由 Composer 生成,不属于 PHPMailer 仓库本身。

如果你不用 Composer 而是手动引入类文件,按 README 的“Minimal installation”一节:至少需要 src/PHPMailer.php;使用 SMTP 时还需要 src/SMTP.php;只有用 POP-before-SMTP 时才需要 src/POP3.php;不向用户展示错误信息时可省略 language 目录。

另外注意:通过 Composer 或 zip 包安装时不包含 examples 目录,本文引用的示例代码需要 git clone 仓库后在 examples 目录查看。

三种方式的前提条件与差异

选择依据都来自仓库文档,按运行环境对照:

1.mail()函数(examples/mail.phps)

  • 使用 PHP 内置的mail()函数,是三者中最简单的用法;
  • 依赖本机存在本地邮件服务器。PHP 的mail()函数通常经由本地邮件服务器发送,在 Linux、BSD、macOS 上通常有 sendmail 二进制程序顶在前面,而Windows 上一般没有本地邮件服务器(见 examples/README.md 对mail.phps的说明);
  • README 的“Why you might need it”一节给出明确态度:mail()应尽量避免使用,连 localhost 的 SMTP 都比它更快、更安全
  • mail.phps没有调用任何is*()切换方法,直接按默认传输方式发送。

2. sendmail 程序(examples/sendmail.phps)

  • sendmail 是一个程序(通常出现在 Linux/BSD、OS X 及其他类 UNIX 系统上),可以不用经历完整的 SMTP 会话就把消息提交给本地邮件服务器;
  • 文档评价是“可能是最快的发送机制,但错误报告功能较弱”(lacks some error reporting features);
  • 通过$mail->isSendmail()切换。从 src/PHPMailer.php#L981-L991 可以看到它的行为:读取 php.ini 的sendmail_path,如果该值中不含sendmail字样,则使用/usr/sbin/sendmail,否则使用sendmail_path配置的值。

3. SMTP(examples/smtp.phps、examples/smtp_no_auth.phps)

  • 通过 PHPMailer 内置的 SMTP 客户端直接连接 SMTP 服务器,所有平台都不需要本地邮件服务器,Windows 环境的唯一可行路径;
  • 支持认证(LOGIN、PLAIN、CRAM-MD5、XOAUTH2)以及 SMTPS 和 SMTP+STARTTLS 传输(README Features 一节);
  • 通过$mail->isSMTP()切换。

可以这样归纳判断路径:没有本地邮件服务器(典型为 Windows)→ 只能选 SMTP;有本地邮件服务器、要最简单 →mail();有 sendmail 类程序、追求提交速度且能接受弱错误报告 → sendmail;而 README 的官方立场是把 SMTP(哪怕是 localhost)作为首选。

配置示例

三种示例的邮件内容部分完全相同(读取contents.html、设置纯文本AltBody、附加图片),差异只在传输方式那几行。以下代码摘自仓库示例文件,域名沿用了示例中的example.com——examples/README.md 说明这是 IANA 为文档示例保留的域名(RFC 2606),运行时需替换为你自己的真实邮箱地址。

方式一:mail()(摘自 examples/mail.phps)

//Import the PHPMailer class into the global namespace use PHPMailer\PHPMailer\PHPMailer; require '../vendor/autoload.php'; //Create a new PHPMailer instance $mail = new PHPMailer(); //Set who the message is to be sent from $mail->setFrom('from@example.com', 'First Last'); //Set an alternative reply-to address $mail->addReplyTo('replyto@example.com', 'First Last'); //Set who the message is to be sent to $mail->addAddress('whoto@example.com', 'John Doe'); //Set the subject line $mail->Subject = 'PHPMailer mail() test'; //Read an HTML message body from an external file, convert referenced images to embedded, //convert HTML into a basic plain-text alternative body $mail->msgHTML(file_get_contents('contents.html'), __DIR__); //Replace the plain text body with one created manually $mail->AltBody = 'This is a plain-text message body'; //Attach an image file $mail->addAttachment('images/phpmailer_mini.png'); //send the message, check for errors if (!$mail->send()) { echo 'Mailer Error: ' . $mail->ErrorInfo; } else { echo 'Message sent!'; }

方式二:sendmail(摘自 examples/sendmail.phps),与上面相比只多一行:

//Set PHPMailer to use the sendmail transport $mail->isSendmail();

方式三:SMTP(带认证)(摘自 examples/smtp.phps 的传输配置部分)

//SMTP needs accurate times, and the PHP time zone MUST be set //This should be done in your php.ini, but this is how to do it if you don't have access to that date_default_timezone_set('Etc/UTC'); require '../vendor/autoload.php'; $mail = new PHPMailer(); //Tell PHPMailer to use SMTP $mail->isSMTP(); //Enable SMTP debugging //SMTP::DEBUG_OFF = off (for production use) //SMTP::DEBUG_CLIENT = client messages //SMTP::DEBUG_SERVER = client and server messages $mail->SMTPDebug = SMTP::DEBUG_SERVER; //Set the hostname of the mail server $mail->Host = 'mail.example.com'; //Set the SMTP port number - likely to be 25, 465 or 587 $mail->Port = 25; //Whether to use SMTP authentication $mail->SMTPAuth = true; //Username to use for SMTP authentication $mail->Username = 'yourname@example.com'; //Password to use for SMTP authentication $mail->Password = 'yourpassword';

HostPortUsernamePassword替换为你的 SMTP 服务器实际值。若服务器不接受匿名发信,参考 examples/smtp_no_auth.phps,它去掉认证配置并注明SMTPAuth = false是默认值,无需显式设置。

需要 TLS 加密和认证的服务商(如 Gmail)有现成配置:examples/gmail.phps 连接smtp.gmail.com的 587 提交端口,启用 TLS 和认证;README 也把 Gmail 示例列为入门推荐起点。README 主示例中则展示了SMTPSecure的两种取值:PHPMailer::ENCRYPTION_SMTPS对应 465 端口,PHPMailer::ENCRYPTION_STARTTLS对应 587 端口。

调试时SMTPDebugSMTP::DEBUG_SERVER(输出客户端和服务器双方的消息);生产环境应改回SMTP::DEBUG_OFF,示例注释里明确标注 DEBUG_OFF 是 for production use。

验证发送结果与本地测试

三种示例用同一种方式判断结果:$mail->send()返回布尔值,失败时读取$mail->ErrorInfo

if (!$mail->send()) { echo 'Mailer Error: ' . $mail->ErrorInfo; } else { echo 'Message sent!'; }

也可以改用异常模式:new PHPMailer(true)构造时传入true即启用异常,send()失败会抛出Exception,在 catch 中读取$mail->ErrorInfo(README 的“Simple Example”和 examples/exceptions.phps 都采用这种写法)。

反复调试时不要往真实收件人发测试邮件,仓库提供了不真正外发的验证手段(见 examples/README.md 的“About testing email sending”一节):

  • mail/sendmail方式:用测试套件里的 test/fakesendmail.sh,这是一个模拟 sendmail 的 shell 脚本,专用于测试 PHPMailer 的 'mail' 或 'sendmail' 方法;
  • 测 SMTP 方式:用假 SMTP 服务器,如 FakeEmail(Python,带 Web 界面)、Postfix 自带的 smtp-sink(PHPMailer 的 CI 测试就用它)、smtp4dev、MailHog 等,它们像真实服务器一样响应但不外发邮件,可用于验证认证和错误处理;
  • 用 msglint(IETF 的 MIME 结构分析器)检查消息格式是否符合规范;
  • 若要真实检查邮件配置(SPF、DKIM、DMARC 等),文档列出了 aboutmy.email 这类在线服务。

运行示例文件前注意 examples/README.md 的安全说明:示例以.phps后缀提供,通常会被 PHP 以语法高亮方式显示而不是执行;如果要放到 Web 服务器运行,必须先改名为.php,并且不要把真实密码写进这些文件里。

限制与选择结论

  • mail()与 sendmail 都要求本机有可用的本地邮件服务器或 sendmail 程序,Windows 一般不具备这一条件,此时只有 SMTP 可选;文档同时建议遇到这种情况“安装本地邮件服务器,或使用远程服务器走 SMTP”。
  • sendmail 方式错误报告能力弱于 SMTP,出问题时可用信息有限。
  • README 对mail()的立场明确:应尽量避免使用它,SMTP(哪怕是 localhost)更快也更安全。
  • 因此默认主路径是:有 SMTP 账号就用isSMTP();确认本机有 sendmail 类程序且需要最快提交时才考虑isSendmail()mail()仅在已有本地邮件服务器、且希望最简配置时使用。
  • 若发送量较大(如群发),SMTP 方式可参考 examples/mailing_list.phps,它利用 SMTP keepalive 避免每条消息都重新连接和认证。

【免费下载链接】PHPMailerThe classic email sending library for PHP项目地址: https://gitcode.com/GitHub_Trending/ph/PHPMailer

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/14 18:27:37

Pulsar Developer Day 2025:云原生消息中间件技术与应用

1. Pulsar Developer Day 2025:消息中间件领域的年度技术盛会 Pulsar Developer Day作为Apache Pulsar社区的年度旗舰活动,将在COSCon25大会期间重磅登场。这场技术盛会聚焦云原生消息中间件的最新进展和实践经验,为开发者提供了一个深度交流…

作者头像 李华
网站建设 2026/9/14 18:26:35

Flutter与鸿蒙开发白噪音APP实战指南

1. 项目背景与核心价值作为一名经历过多个跨平台开发项目的移动端开发者,我最近用Flutter框架为鸿蒙系统开发了一款睡眠白噪音APP。这个技术组合带来的开发效率提升令人惊喜——同一套Dart代码经过适配后,既能运行在鸿蒙设备上,又能兼容Andro…

作者头像 李华
网站建设 2026/9/14 18:25:24

小爱音箱接ChatGPT:MiGPT完整配置教程

小爱音箱接ChatGPT:MiGPT完整配置教程 【免费下载链接】mi-gpt 🏠 将小爱音箱接入 ChatGPT 和豆包,改造成你的专属语音助手。 项目地址: https://gitcode.com/GitHub_Trending/mi/mi-gpt MiGPT 把小爱音箱接入 ChatGPT、豆包等大模型&…

作者头像 李华