PHPMailer 如何用 SMTPOptions 为 SMTP TLS 连接配置自定义 SSL 连接参数
2026/9/14 19:22:05 网站建设 项目流程

PHPMailer 如何用 SMTPOptions 为 SMTP TLS 连接配置自定义 SSL 连接参数

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

当你用 PHPMailer 通过 SMTP 发信并启用 TLS(465 端口的 SMTPS 或 587 端口的 STARTTLS)时,底层的 TLS 握手行为(比如校验对端证书、指定 CA 证书文件、限制校验深度)默认由 PHP 的流上下文决定。如果需要向这条连接传入自定义的 SSL 参数,PHPMailer 提供了SMTPOptions属性:它是一个数组,在通过 SMTP 连接时会被原样传给stream_context_create()。仓库中的示例 examples/ssl_options.phps 展示了完整的用法,本文按这个示例梳理出可执行的配置路径。

SMTPOptions 在源码中的位置与作用

在 src/PHPMailer.php 中,该属性的定义是:

/** * Options array passed to stream_context_create when connecting via SMTP. * * @var array */ public $SMTPOptions = [];

它的工作链路在源码中可以确认:

  1. PHPMailer::smtpConnect()在未显式传入参数时,会把实例上的$this->SMTPOptions作为 options 使用(见 src/PHPMailer.php);
  2. SMTP::connect()接收这个 options 数组,注释说明它是 “An array of options for stream_context_create()”(见 src/SMTP.php);
  3. 实际建连时执行stream_context_create($options),再把生成的上下文交给stream_socket_client()打开host:port(见 src/SMTP.php)。

因此SMTPOptions的数组结构必须与stream_context_create()兼容。changelog.md 记录该属性于 Version 5.2.10(May 4th 2015)加入:“Expose stream_context_create options via new SMTPOptions property”,所以 6.x 版本均可使用。

两个前提条件需要注意:

  • 示例文件说明 SMTP 依赖精确时间,时区必须设置好;没有 php.ini 权限时可用date_default_timezone_set()(examples/ssl_options.phps)。
  • 使用 STARTTLS 或 SMTPS 加密时,PHPMailer 会检查 OpenSSL 扩展(通过OPENSSL_ALGO_SHA256常量判断),缺失时抛出 “extension missing openssl” 异常(见 src/PHPMailer.php)。

另外,SMTP::getSMTPConnection()中有一个回退分支:当stream_socket_client不可用时改用fsockopen,注释明确说它 “should work in more places, but is missing some features”——回退路径不会传入流上下文(见 src/SMTP.php)。也就是说SMTPOptions只在走stream_socket_client路径时生效。

准备环境

推荐用 Composer 安装(README.md):

composer require phpmailer/phpmailer

vendor目录和vendor/autoload.php由 Composer 生成,不属于 PHPMailer 本身。5.2 分支已停止维护,官方建议 PHP 5.5+ 使用 6.x 版本。

配置 TLS 连接与 SMTPOptions

以下代码整理自 examples/ssl_options.phps,示例值(主机、证书路径、账号密码)需要替换为你自己的环境:

<?php use PHPMailer\PHPMailer\PHPMailer; use PHPMailer\PHPMailer\SMTP; //SMTP needs accurate times, and the PHP time zone MUST be set 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_CONNECTION; //Set the hostname of the mail server(示例值,替换为你的 SMTP 主机) $mail->Host = 'smtp.example.com'; //Set the SMTP port number: // - 465 for SMTP with implicit TLS, a.k.a. RFC8314 SMTPS or // - 587 for SMTP+STARTTLS $mail->Port = 465; //Set the encryption mechanism to use: // - SMTPS (implicit TLS on port 465) or // - STARTTLS (explicit TLS on port 587) $mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS; //Custom connection options //Note that these settings are INSECURE $mail->SMTPOptions = array( 'ssl' => [ 'verify_peer' => true, 'verify_depth' => 3, 'allow_self_signed' => true, 'peer_name' => 'smtp.example.com', 'cafile' => '/etc/ssl/ca_cert.pem', ], ); //Whether to use SMTP authentication $mail->SMTPAuth = true; $mail->Username = 'username@example.com'; $mail->Password = 'yourpassword'; $mail->setFrom('from@example.com', 'First Last'); $mail->addAddress('whoto@example.com', 'John Doe'); $mail->Subject = 'PHPMailer SMTP options test'; $mail->msgHTML(file_get_contents('contents.html'), __DIR__); if (!$mail->send()) { echo 'Mailer Error: ' . $mail->ErrorInfo; } else { echo 'Message sent!'; }

关键点说明:

  • 'ssl'键下的每个选项都是传给流上下文的 SSL 参数。示例中出现了verify_peerverify_depthallow_self_signedpeer_namecafile五个选项,其中peer_nameHost一致,cafile指向一份 CA 证书文件(示例值/etc/ssl/ca_cert.pem需要换成你实际存在的证书路径)。
  • 示例中特意标注了警告:这组设置(含allow_self_signed => true)是 “INSECURE” 的,原注释为 “Note that these settings are INSECURE”。生产环境是否保留这些值,需要由你按邮件服务商的证书情况自行决定,文档没有给出进一步的安全配置建议。
  • 如果服务端只开放 587 端口,把Port改为 587、SMTPSecure改为 STARTTLS 对应值即可;465 对应 SMTPS(implicit TLS),两者二选一,见 examples/ssl_options.phps 的注释。
  • 端口和加密方式也可在Host上用ssl:///tls://前缀或端口号单独指定,smtpConnect()会对 Host 做解析(见 src/PHPMailer.php)。

验证连接与发送结果

验证方式分三层,均出自仓库文档:

  1. 调试输出SMTPDebug控制调试级别——SMTP::DEBUG_OFF(生产环境关闭)、SMTP::DEBUG_CLIENT(仅客户端消息)、SMTP::DEBUG_SERVER(客户端与服务端消息),示例使用SMTP::DEBUG_CONNECTION查看连接过程(见 examples/ssl_options.phps)。
  2. 连接成功判定SMTP::connect()会读取服务端的公告回复,响应码为220时返回true554时会发送 QUIT,其他非 220 响应则关闭连接并返回false(见 src/SMTP.php)。调试输出中可以看到Connection: opening to host:port, ... options=...SERVER -> CLIENT: ...这类行。
  3. 发送结果:示例以send()的返回值判断——失败时输出'Mailer Error: ' . $mail->ErrorInfo,成功时输出'Message sent!'(见 examples/ssl_options.phps)。

限制与注意事项

  • SMTPOptions只在stream_socket_client可用时生效;PHPMailer 回退到fsockopen的路径“missing some features”,不传入流上下文(src/SMTP.php)。
  • STARTTLS / SMTPS 依赖 OpenSSL 扩展,缺失时抛异常而不是静默降级。
  • 示例中的整组ssl参数被原作者标注为不安全配置,仅作为演示如何传参,是否照抄取决于你的信任链需求。
  • SMTPOptions的数组必须能被stream_context_create()接受;src/PHPMailer.php 的 PHPDoc 明确其为 “Options array passed to stream_context_create when connecting via SMTP”。

如果需要更多连接行为的细节,可继续阅读 src/SMTP.php 中connect()的完整实现;完整可运行示例见 examples/ssl_options.phps。

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

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询