dimarick / net_smtp
SMTP协议的实现
Requires
- php: >=5.6.0
- dimarick/net_socket: v2.0.0beta2@dev
Requires (Dev)
This package is not auto-updated.
Last update: 2024-09-23 06:57:28 UTC
README
用户文档
目录
1 依赖关系
1.1 PEAR_Error
类
Net_SMTP包使用PEAR_Error类来处理所有错误。
1.2 Net_Socket
包
使用Net_Socket包作为所有网络通信的基础。可以通过$socket_options构造参数指定连接选项。
$socket_options = array('ssl' => array('verify_peer_name' => false)); $smtp = new Net_SMTP($host, null, null, false, 0, $socket_options);
注意:PHP 5.6引入了OpenSSL更改。默认情况下现在启用了对等证书验证。虽然不推荐,但可以使用$socket_options来禁用对等验证(如上所示)。
1.3 Auth_SASL
包
Auth_SASL包是一个可选的依赖项。如果可用,Net_SMTP包将能够支持DIGEST-MD5和CRAM-MD5 SMTP认证方法。否则,仅提供LOGIN和PLAIN方法。
2 错误处理
如果发生错误,Net_SMTP类的所有公共方法都返回一个PEAR_Error对象。检查PEAR_Error对象的标准方法是通过使用PEAR::isError()
if (PEAR::isError($error = $smtp->connect())) { die($error->getMessage()); }
3 SMTP认证
Net_SMTP包支持SMTP认证标准(如RFC-2554定义)。Net_SMTP包按优先级顺序支持以下认证方法:
3.1  >DIGEST-MD5
DIGEST-MD5认证方法使用RSA数据安全公司的MD5消息摘要算法。它被认为是SMTP认证中最安全的方法。
注意:DIGEST-MD5认证方法仅在对AUTH_SASL包可用时受支持。
3.2  >CRAM-MD5
在安全性方面,CRAM-MD5认证方法已被DIGEST-MD5方法取代。它在此提供是为了与可能不支持较新DIGEST-MD5算法的旧SMTP服务器兼容。
注意:CRAM-MD5认证方法仅在对AUTH_SASL包可用时受支持。
3.3 LOGIN
LOGIN 身份验证方法使用 Base64 编码方案对用户的密码进行加密。由于解密 Base64 编码的字符串很简单,因此 LOGIN 不被认为是一种安全的身份验证方法,应该避免使用。
3.4 PLAIN
PLAIN 身份验证方法以明文形式发送用户的密码。这种身份验证方法不安全,应该避免使用。
4 安全连接
如果已在 PHP 中启用了 安全套接字传输,则可以建立到远程 SMTP 服务器的安全连接
$smtp = new Net_SMTP('ssl://mail.example.com', 465);
以下示例使用 ssl://
传输连接到 mail.example.com
的 465 端口(一个常见的 SMTPS 端口)。
5 发送数据
消息数据使用 data()
方法发送。数据可以提供为一个字符串,或者作为一个打开的文件资源。
如果提供字符串,它将通过 数据引用 系统传递,并作为单个块发送到套接字连接。所有这些操作都是基于内存的,因此发送大消息可能会导致内存使用量很高。
如果提供打开的文件资源,则 data()
方法将逐行从文件中读取消息数据。每个块将引用并单独发送到套接字连接,从而减少整个数据发送操作的内存开销。
可以通过将可选的第二个参数作为 data()
传递来单独指定标题数据,而不是消息体数据。这对于使用打开的文件资源提供消息数据时尤其有用,因为它允许在运行时动态构建标题字段(如 Subject:)。
$smtp->data($fp, "Subject: My Subject");
6 数据引用
默认情况下,所有输出字符串数据都根据 SMTP 标准进行引用。这意味着所有本机 Unix (\n
) 和 Mac (\r
) 换行符都转换为 Internet 标准的 CRLF (\r\n
) 换行符。此外,由于 SMTP 协议使用单个前导点 (.
) 来表示消息数据的结束,因此原始数据字符串中的单个前导点会被“加倍”(例如,“..
”)。
当涉及大量数据时,这些字符串转换可能很昂贵。例如,Net_SMTP 包不了解 MIME 部分(它只是将 MIME 消息视为一个大的字符字符串),因此它无法在查找可能需要引用的字符时跳过非文本附件。
因此,可以通过扩展 Net_SMTP 类来实现自定义引用例程。只需创建一个基于 Net_SMTP 类的新类,并重新实现 quotedata()
方法
require 'Net_SMTP.php'; class Net_SMTP_custom extends Net_SMTP { function quotedata($data) { /* Perform custom data quoting */ } }
注意,$data
参数将以引用的方式传递给 quotedata()
函数 by reference。这意味着可以直接对 $data
进行操作。这也消除了在 quotedata()
方法之间复制大型 $data
字符串的开销。
7 服务器响应
Net_SMTP 包保留服务器的最后响应以供进一步检查。getResponse()
方法返回一个包含服务器响应代码(作为整数)和响应参数(作为字符串)的 2 元组(两个元素的数组)。
成功连接后,可以通过 getGreeting()
方法获取服务器的问候字符串。
8 调试
Net_SMTP 包包含内置的调试输出例程(默认情况下禁用)。调试输出必须通过 setDebug()
方法显式启用
$smtp->setDebug(true);
默认情况下,调试消息将发送到标准输出流。如果需要更多的输出控制,您可以可选地安装自己的调试处理程序。
function debugHandler($smtp, $message) { echo "[$smtp->host] $message\n"; } $smtp->setDebug(true, "debugHandler");
9 示例
9.1 基本用法
以下脚本演示了如何使用 Net_SMTP 包发送简单的电子邮件消息
require 'Net/SMTP.php'; $host = 'mail.example.com'; $from = 'user@example.com'; $rcpt = array('recipient1@example.com', 'recipient2@example.com'); $subj = "Subject: Test Message\n"; $body = "Body Line 1\nBody Line 2"; /* Create a new Net_SMTP object. */ if (! ($smtp = new Net_SMTP($host))) { die("Unable to instantiate Net_SMTP object\n"); } /* Connect to the SMTP server. */ if (PEAR::isError($e = $smtp->connect())) { die($e->getMessage() . "\n"); } /* Send the 'MAIL FROM:' SMTP command. */ if (PEAR::isError($smtp->mailFrom($from))) { die("Unable to set sender to <$from>\n"); } /* Address the message to each of the recipients. */ foreach ($rcpt as $to) { if (PEAR::isError($res = $smtp->rcptTo($to))) { die("Unable to add recipient <$to>: " . $res->getMessage() . "\n"); } } /* Set the body of the message. */ if (PEAR::isError($smtp->data($subj . "\r\n" . $body))) { die("Unable to send data\n"); } /* Disconnect from the SMTP server. */ $smtp->disconnect();