PHP开发者一般都是使用PHPMailer发送邮件,不知道你有没有看过它的源码呢?其实并不难,核心在于SMTP协议,下面我分享下如何不依赖PHPMailer来发送邮件。
我选择使用QQ邮箱的SMTP服务器,其他邮箱服务商比如网易、新浪都是可以的。
首先建立TCP连接:
$hostname = ‘smtp.qq.com’; // 邮件服务器
$port = 465; // 服务器端口
$username = ‘crazymus@foxmail.com’; // 你的邮箱账号
$password = ‘*************’; // 你的邮箱密码,QQ邮箱使用的不是密码,是授权码,登录邮箱设置
$sendTo = ‘291445576@qq.com’; // 收件人
$socket = fsockopen(‘ssl://’ . $hostname, $port, $errno, $errmsg);
if (!$socket) throw new \RuntimeException(‘create socket failed’, 1);
为什么要使用ssl连接?因为QQ邮箱提供了ssl加密的通道,我们和服务器之间的数据传输都将是加密的。你也可以不使用ssl连接,去掉ssh://前缀,使用端口25就行,但并不推荐这样。在如今复杂的互联网环境中,明文传输数据是非常危险的,很容易被他人截获敏感信息。
然后,我们按照SMTP协议准备好需要发送的命令。
$array = [
“HELO crazymus\r\n”, // 打招呼
“auth login\r\n”, // 请求认证
base64_encode($username) . “\r\n”, // 用户名,需要base64编码
base64_encode($password) . “\r\n”, // 密码,需要base64编码
“mail from:\r\n”, // 发件人
“rcpt to:\r\n”, // 收件人
“data\r\n”, // 即将发送的是邮件内容
“subject:这是邮件标题\r\nfrom:$username\r\nto:$sendTo\r\n\r\n这是邮件内容\r\n.\r\n”, // 邮件内容
];
每条命令都用换行符结束,windows下是\r\n,如果你使用Linux或者Mac,就换成\n和\r。需要注意的是最后一条命令,它是邮件的内容。邮件内容包含header和body两部分,用换行符隔开。如果你熟悉HTTP协议,就会发现这很容易理解。最后用\r\n.\r\n (两个换行符包裹的点号)来标识邮件结束。服务器收到这个标识后,就会开始发送邮件了。
接下来,我们依次向服务器发送上面的命令,并输出服务器返回值:
foreach ($array as $command) {
fwrite($socket, $command); // 发送命令
$resp = fgets($socket); // 获取一行响应内容
echo $resp;
}
flose($socket); // 关闭TCP连接
如果顺利的话,应该会依次输出下面的内容:
220 newxmesmtplogicsvrszc5.qq.com XMail Esmtp QQ Mail Server.
250-newxmesmtplogicsvrszc5.qq.com-100.77.8.93-115229658
250-SIZE 73400320
250 OK
334 VXNlcm5hbWU6
334 UGFzc3dvcmQ6
235 Authentication successful
250 OK.
250 OK
354 End data with ..
250 OK: queued as.
最后一行是250状态码,表示邮件发送完毕,我们可以根据它来判断邮件是否发送成功。下面列出SMTP协议常见的状态码:
501 参数格式错误
502 命令不可实现
503 错误的命令序列
504 命令参数不可实现
211 系统状态或系统帮助响应
214 帮助信息
220 <domain>服务就绪
221 <domain>服务关闭
421 <domain>服务未就绪,关闭传输信道
250 要求的邮件操作完成
251 用户非本地,将转发向<forward-path>
450 要求的邮件操作未完成,邮箱不可用
550 要求的邮件操作未完成,邮箱不可用
451 放弃要求的操作;处理过程中出错
551 用户非本地,请尝试<forward-path>
452 系统存储不足,要求的操作未执行
552 过量的存储分配,要求的操作未执行
553 邮箱名不可用,要求的操作未执行
354 开始邮件输入,以”.”结束
554 操作失败
这样我们就用SMTP协议简单的实现了发送邮件。上面的例子只是发送了纯文本,其实HTML也是支持的,只要在邮件header中定义了正确的content-type,就可以发送HTML内容了,这里就不再深入讲解了,大家可以在自行查阅相关资料!