简体   繁体   中英

Sending email with mail()

I'm making kind of email sender class and i have some problems:

  • Some email services like russian mail.ru don't understand encoding of the message and show my UTF-8 mail in Windows-1251 charset. GMail is ok with that.
  • All email services show text/html as plain text.
  • Multipart messages broken as well.

Also i should note, that i'm sending it from local server build on OpenServer using GMail SMTP server.
My opinion problem in kind of mybullshitcode or in smth that covers Content-type header.

Theres a code:

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).'?=';
    }
}

I tried to make subj and to headers in base64_encode - seems hopeless.

All kind of help will be appreciated!

UPD: Quoted-printable variant

    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--";

UPD2: Using PHPMailer... GMail email subject with cyrillic chars in end.

Here is the subject. Ðто заголовок!

The body is acceptable:

This is the HTML message body in bold!. Такое сообщение!

Code:

$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!';

So maybe i need to use iconv? Theres subj conversion UTF-8 to Windows-1252...

Have you thought of using phpmailer Here

It does it all for you but requires to use your email and email password in config values. But its secure and your information wont be released so thats a option you could use.

According to http://otvet.mail.ru/question/92734494 you should do two things:

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

And set the encoding of html page to utf-8. So you should add the following as the first line in PHP code.

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

According to sending mail in UTF-8 you should also use quoted_printable_encode() and have Content-Transfer-Encoding: quoted-printable instead of Content-Transfer-Encoding: 7bit

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM