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 = [];它的工作链路在源码中可以确认:
PHPMailer::smtpConnect()在未显式传入参数时,会把实例上的$this->SMTPOptions作为 options 使用(见 src/PHPMailer.php);SMTP::connect()接收这个 options 数组,注释说明它是 “An array of options for stream_context_create()”(见 src/SMTP.php);- 实际建连时执行
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/phpmailervendor目录和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_peer、verify_depth、allow_self_signed、peer_name、cafile五个选项,其中peer_name与Host一致,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)。
验证连接与发送结果
验证方式分三层,均出自仓库文档:
- 调试输出:
SMTPDebug控制调试级别——SMTP::DEBUG_OFF(生产环境关闭)、SMTP::DEBUG_CLIENT(仅客户端消息)、SMTP::DEBUG_SERVER(客户端与服务端消息),示例使用SMTP::DEBUG_CONNECTION查看连接过程(见 examples/ssl_options.phps)。 - 连接成功判定:
SMTP::connect()会读取服务端的公告回复,响应码为220时返回true;554时会发送 QUIT,其他非 220 响应则关闭连接并返回false(见 src/SMTP.php)。调试输出中可以看到Connection: opening to host:port, ... options=...与SERVER -> CLIENT: ...这类行。 - 发送结果:示例以
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),仅供参考