使用mail()发送电子邮件

3

我正在制作一种电子邮件发送器类,但遇到了一些问题:

  • 某些电子邮件服务(例如俄罗斯的mail.ru)无法理解邮件的编码方式,并将我的UTF-8邮件显示为Windows-1251字符集。Gmail没有这个问题。
  • 所有电子邮件服务都将text/html显示为纯文本。
  • 多部分消息也无法正常显示。

此外,我应该指出,我是从基于OpenServer搭建的本地服务器使用Gmail SMTP服务器发送邮件。
我的观点是问题出在我的代码中或者是涉及Content-type头的某些东西。

以下是代码:

class _EMAIL
{
    protected $type;
    protected $to;
    protected $subject;
    protected $plain;
    protected $html;
    protected $charset;
    protected $headers = array(
    'MIME-Version'  => '1.0',
    // 'Content-type'   => '',
    // 'From'           => '',
    // 'Cc'         => '',
    // 'Bcc'            => '',
    // 'Reply-To'       => '',
    // 'Subject'        => '',
    // 'Return-Path'    => ''
    );

    public function __construct($to, $subj, $datacharset, $sendcharset)
    {
        $this->to = self::hencode($to, $datacharset, $sendcharset);
        $this->subject = self::hencode($subj, $datacharset, $sendcharset);
        $this->headers['Subject'] = $this->subject;
        $this->datacharset = $datacharset;
        $this->sendcharset = $sendcharset;
    }
    public function setHeader($el, $val)
    {
        $this->headers[$el] = $val;
    }
    public function setPlain($message)
    {
        $this->plain = iconv($this->datacharset, $this->sendcharset, $message);
    }
    public function setHTML($message)
    {
        $this->html = iconv($this->datacharset, $this->sendcharset, $message);
    }


    /* Static */
    public static function send($to, $mail)
    {
        if ($mail->plain !== null && $mail->html !== null)
        {
            $r = sha1(uniqid());
            $mail->headers['Content-Type'] = "multipart/alternative; boundary=$r";
            $message = "--$r
Content-Type: text/plain; charset=".$mail->sendcharset."
Content-Transfer-Encoding: 7bit

".$mail->plain."

--$r
Content-Type: text/html; charset=".$mail->sendcharset."
Content-Transfer-Encoding: 7bit

".$mail->html."

--$r--";
        } else if ($mail->html !== null) {
            $mail->headers['Content-Type'] = 'text/html; charset='.$mail->sendcharset;
            $message = $mail->html;
        } else if ($mail->plain !== null) {
            $mail->headers['Content-Type'] = 'text/plain; charset='.$mail->sendcharset;
            $message = $mail->plain;
        } else {
            return FALSE;
        }
        $headers = '';
        $mail->to = $mail->to." <$to>";
        $mail->headers['X-Mailer'] = 'PHP/'.phpversion().' - Blabla '.Core::build_info();
        foreach ($mail->headers as $key=>$val)
        {
            $headers .= $key.': '.$val.'\r\n';
        }
        return mail($to, $mail->subject, $message, $headers);
    }

    private static function hencode($str, $data_charset, $send_charset=FALSE)
    {
        if ($send_charset && $data_charset != $send_charset)
        {
            $str = iconv($data_charset, $send_charset, $str);
        } else {
            $send_charset = $data_charset;
        }
        return '=?'.$send_charset.'?B?'.base64_encode($str).'?=';
    }
}

我试图将subjto标头转换为base64编码,但似乎无望。

所有形式的帮助都将不胜感激!

更新:Quoted-printable变体

    public function setPlain($message)
    {
        $this->plain = quoted_printable_encode(iconv($this->datacharset, $this->sendcharset, $message));
    }
    public function setHTML($message)
    {
        $this->html = quoted_printable_encode(iconv($this->datacharset, $this->sendcharset, $message));
    }

            $message = "--$r
Content-Type: text/plain; charset=".$mail->sendcharset."
Content-Transfer-Encoding: quoted-printable

".$mail->plain."

--$r
Content-Type: text/html; charset=".$mail->sendcharset."
Content-Transfer-Encoding: quoted-printable

".$mail->html."

--$r--";

更新2:使用PHPMailer... GMail邮件主题以西里尔字母结尾。

这是主题。这是一个问候语!

邮件正文可接受:

这是粗体的HTML消息正文!这是一条消息!

代码:

$mail = new _EMAIL;
$mail->From = 'admin@ss133d.ru';
$mail->FromName = 'SS133D Administration';
$mail->addAddress($email, $login);
$mail->addReplyTo('admin@ss133d.ru', 'SS133D Administration');
$mail->isHTML(true);

$mail->Subject = 'Here is the subject. Это заголовок!';
$mail->Body    = 'This is the HTML message body <b>in bold!</b>. Такое <b>сообщение</b>!';
$mail->AltBody = 'This is the body in plain text for non-HTML mail clients. А это без HTML!';

也许我需要使用iconv?有一个将UTF-8转换为Windows-1252的主题...


不使用现有库的原因是什么? - deviantfan
是的。让我的开源项目依赖外部库可能会在未来“伤害”我… 所以… 只能从头开始 - 只有强硬 :D 或者在 PHP 核心 5.3 之后有一些内置的东西? - RussianVodka
1
那么去学习与发送邮件相关的RFC吧。 - CBroe
@RussianVodka 你就像 Cave Johnson :=) - Andro
1
@Andro47 处理它 :D - RussianVodka
2个回答

2

你有没有想过使用phpmailer这里

它可以为你完成一切,但需要在配置值中使用你的电子邮件和电子邮件密码。但是它是安全的,你的信息不会被泄露,所以这是一个可以使用的选项。


明天见。 - RussianVodka
好的!我尝试在我的项目中使用PHPMailer。请参见更新2。 - RussianVodka
好的。我在phpmailer类中将iso编码更改为utf-8,现在一切正常!谢谢! - RussianVodka

0

根据http://otvet.mail.ru/question/92734494,你应该做两件事:

$headers[] = "Content-type: text/plain; charset=utf-8"; 

并将HTML页面的编码设置为UTF-8。因此,您应该在PHP代码的第一行添加以下内容。

header('Content-type: text/plain; charset=utf-8');

根据使用UTF-8发送邮件,您还应该使用quoted_printable_encode()函数,并将Content-Transfer-Encoding: 7bit替换为Content-Transfer-Encoding: quoted-printable

嗯...我不明白你的意思。我看到了那个答案...但是... 为什么我要把我的HTML页面转换成utf-8格式呢?首先,我的页面已经是utf-8格式了。其次,这与实际邮件有什么关系呢?我认为64base更好...而且正如你在我的代码中看到的,纯文本消息没有那些头部信息... - RussianVodka
尽可能多地查看 :) 这是我在GMail Plain+HTML中得到的结果。 - RussianVodka
你能输出 $message 吗?它最初是以 utf-8 格式吗? - keiv.fly
是的。它是100%的utf-8编码。 - RussianVodka
让我们在聊天中继续这个讨论:点击此处进入聊天室 - RussianVodka
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接