PHP使用STMP协议发送邮件

STMP(Simple Mail Transfer Protocol,简单邮件传输协议)是属于传输层的协议。

STMP服务器是遵循SMTP协议的发送邮件服务器,用来发送或者中转发出的电子邮件。客户端通过SMTP命令与SMTP服务器进行交互。首先,客户端需要和服务器建立TCP连接,然后客户端发送HELO命令,服务端回应OK,客户端再发送AUTH LOGIN命令登入SMTP服务器,输入用户名和密码(注意,用户名和密码都需要使用base64加密,而且为了安全,密码为授权码)。登入进去后,客户端发送MAIL FROM命令设置“邮件发送人”、RCPT TO设置“邮件接收人”,可以有多个RCPT行。服务器回应OK。接着客户端发送DATA命令,服务器返回End data with <CR><LF>.<CR><LF>,意思是以\r\n.\r\n作为邮件主题的结尾标识符。然后就需要输入正文了,FromToSubjectBody等,最后以\r\n.\r\n结尾。如果没有结尾标识符,服务器会一直等待直到超时,如果有服务器就会将邮件信息放入队列再发送。最后客户端以QUIT命令退出。

SMTP协议是建立在TCP协议上的,我们可以用Socket跟服务器进行交互,PHP里面有个fsockopen()函数,已经为我们做好了一切。

Talk is cheap. Show me the code.

<?php

class SMTPMail
{
    private $host;
    private $port;
    private $username;
    private $password; // 此处为授权码
    private $sock;
    private $mail_format; // 0普通文本 1HTML

    public function __construct($host, $port, $username, $password, $mail_format = 1)
    {
        $this->host = $host;
        $this->port = $port;
        $this->username = $username;
        $this->password = $password;
        $this->mail_format = $mail_format;

        $this->sock = fsockopen($this->host, $this->port, $errno, $errstr, 10);

        if (!$this->sock) {
            throw new \Exception("Error number: $errno, Error message: $errstr");
        }

        $response = fgets($this->sock);
        if (strstr($response, '220') === false) {
            throw new \Exception("Server error: $response");
        }
    }

    /**
     * 將命令发送到服务器执行
     */
    private function do_command($cmd, $return_code)
    {
        fwrite($this->sock, $cmd);

        $response = fgets($this->sock);
        if (strstr($response, "$return_code") === false) {
            return false;
        }

        print_r($cmd);
        print_r($response);

        return true;
    }

    /**
     * 发送邮件
     */
    public function send_mail($from, $to, $subject, $body)
    {
        $detial = "From: $from" . "\r\n";
        $detial .= "To: $to" . "\r\n";
        $detial .= "Subject: $subject" . "\r\n";

        if ($this->mail_format) {
            $detial .= "Content - Type: text/html;\r\n";
        } else {
            $detial .= "Content - Type: text/plain;\r\n";
        }

        $detial .= "charset = utf-8\r\n\r\n";
        $detial .= $body;

        $this->do_command("HELO stmp.163.com\r\n", 250);
        $this->do_command("AUTH LOGIN\r\n", 334);
        $this->do_command(base64_encode($this->username) . "\r\n", 334);
        $this->do_command(base64_encode($this->password) . "\r\n", 235);
        $this->do_command("MAIL FROM:<$from>" . "\r\n", 250);
        $this->do_command("RCPT TO:<$to>" . "\r\n", 250);
        $this->do_command("DATA\r\n", 354);
        $this->do_command($detial . "\r\n.\r\n", 250);
        $this->do_command("QUIT" . "\r\n", 221);

        return true;
    }
}
$host = 'smtp.163.com';
$port = 25;
$username = ''; // 用户名即邮箱
$password = ''; // 此处为授权码

$from = ''; // 发件人
$to = ''; // 收件人
$subject = 'Test'; // 主题
$content = 'This is a test, thank you.'; // 内容

$mail = new SMTPMail($host, $port, $username, $password);
$mail->send_mail($from, $to, $subject, $content);

 

 

 

参考资料:《PHP核心技术与最佳实践》

posted @ 2020-03-13 17:16  灯无焰  阅读(582)  评论(0编辑  收藏  举报