PHP使用SMTP协议发送邮件

▼魔方 西西 提交于 2020-04-05 17:45:35

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:<$username>\r\n", // 发件人
    "rcpt to:<$sendTo>\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 <CR><LF>.<CR><LF>.
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内容了,这里就不再深入讲解了,大家可以在自行查阅相关资料!

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!