我正在制作一种电子邮件发送器类,但遇到了一些问题:
- 某些电子邮件服务(例如俄罗斯的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).'?=';
}
}
我试图将subj
和to
标头转换为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的主题...