1

当我尝试使用 PHPMailer_v5.1 发送电子邮件时,它可以工作。但是当我尝试自己制作时,我知道结果可能会出错或未发送电子邮件。我的问题是没有发送电子邮件。这是我的代码:

<?php
$fp = fsockopen("ssl://smtp.gmail.com", 465, $errNo, $errStr, 15);
if(!$fp){
    echo "not connected";
}else{
    fputs($fp, "EHLO"."\r\n");
    fputs($fp, "AUTH LOGIN"."\r\n");
    fputs($fp, base64_encode("author@gmail.com")."\r\n");
    fputs($fp, base64_encode("password")."\r\n");
    fputs($fp, "MAIL FROM:<author@gmail.com>"."\r\n");
    fputs($fp, "RCPT TO:<target@gmail.com>"."\r\n");
    fputs($fp, "DATA"."\r\n");
    fputs($fp, "Subject: This is subject"."\r\n");
    fputs($fp, "This is body message"."\r\n");
    fputs($fp, "."."\r\n");
    fputs($fp, "QUIT"."\r\n");
    fclose($fp);
}
?>

对不起,我的英语不好。

4

1 回答 1

1

我认为这里的问题是您将 SMTP 视为单向街道,并且只是在不检查响应的情况下发出命令。

连接后您应该做的第一件事是读取服务器横幅,然后在每个命令之后您应该读取服务器的响应。等待服务器横幅很重要,因为对于繁忙的 MTA,您可能需要等待一分钟才能真正启动事务。这是我为有趣而写的邮件的 EHLO 函数的注释版本:

private function do_ehlo() {
    // most MTAs expect a domain/host name, and the picky ones want the hostname specified here
    // to match the reverse lookup of the IP address.
    $ehlo = sprintf("EHLO %s\r\n", $this->connection_info['domain']);
    $this->log($ehlo, 'out');
    fwrite($this->sock, $ehlo, strlen($ehlo));

    // SMTP responses can span multiple lines, they will look like
    // ###-First line
    // ###-Second line
    // ### Last line
    //
    // Where ### is the 3-digit status code, and every line but the last has a dash between the
    // code and the text.
    while( $get = fgets($this->sock, 1024) ) {
        $this->log($get, 'in');
        if( ! preg_match('/^([0-9]{3})([ -])(.*)$/', $get, $matches) || $matches[1] != '250' ) {
            Throw new Exception('Abnormal EHLO repsonse received: ' . $get);
        }
        // The advertised capabilities of the server in the EHLO response will include the types
        // of AUTH mechanisms that are supported, which is important, because LOGIN is just
        // gussied-up plaintext, and plaintext is bad.
        $this->capabilities[] = trim($matches[3]);
        // stop trying to read from the socket if a space is detected, indicating either a 
        // single-line response, or the last line of a multi-line response.
        if( $matches[2] == ' ' ) { break; }
    }
}

IIRC GMail 对遵守规则特别挑剔,他们可能会因为没有EHLO在. 如果你想变得真正挑剔,你也没有在消息数据中设置标题,我相信这对于严格的服务器来说也是一个很大的诺诺,使用:MAIL FROMRCPT TODatesprintf('Date: %s', date(DATE_RFC2822));

最后,如果您想编写自己的邮件程序,您应该从阅读RF2822RFC821RFC2821 开始。只要确保你手头有一些浓咖啡,否则你很快就会睡着了。

TL;DR: PHPmailer 更容易。

于 2013-05-16T16:19:35.993 回答