欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

[PHP] MIME邮件协议的multipart类型

程序员文章站 2022-06-25 15:54:50
邮件协议中的三种情况,对应下面的三种类型 multipart/mixed可以包含附件。multipart/related可以包含内嵌资源。multipart/alternative 纯文本与超文本共存 1.纯文本的,只需要一块content-type块,不需要multipart块 2.内容是html ......

邮件协议中的三种情况,对应下面的三种类型

multipart/mixed可以包含附件。
multipart/related可以包含内嵌资源。
multipart/alternative 纯文本与超文本共存

1.纯文本的,只需要一块content-type块,不需要multipart块

date: tue, 16 apr 2019 17:35:19 +0800
received: from shihan2@sopans.com([]) by  via http;
 tue, 16 apr 2019 17:35:19 +0800 (cst)
reply-to: shihan2@sopans.com
from: <shihan2@sopans.com>
to: shihan2@sopans.com
subject: =?gbk?b?ztlatlliytq=?=
mime-version: 1.0
x-priority: 3
x-messageid: 1555407319.5028.10108
x-originating-ip: []
x-mailer: sina webmail 4.0
x-sina-mid: 044d8eb6f6ef3f6fae1a32d8b0930f609000000000000002
content-type: text/plain; charset=gbk
content-transfer-encoding: base64

agvsbg8=

2.内容是html的要加两块content-type块内容,一块是html一块是纯文本,并且要增加一块multipart类型块

date: tue, 16 apr 2019 17:36:41 +0800
received: from shihan2@sopans.com([]) by  via http;
 tue, 16 apr 2019 17:36:41 +0800 (cst)
reply-to: shihan2@sopans.com
from: <shihan2@sopans.com>
to: shihan2@sopans.com
subject: =?gbk?b?ztlatlliytq=?=
mime-version: 1.0
x-priority: 3
x-messageid: 1555407401.2205.10152
x-originating-ip: []
x-mailer: sina webmail 4.0
x-sina-mid: 044d8eb6f6ef3f6fae1a32d8b0930f609000000000000002
content-type: multipart/alternative;
         boundary="=-sinamail_alt_849bb6f96e7dc06cb99a08e3f9c84179"

--=-sinamail_alt_849bb6f96e7dc06cb99a08e3f9c84179
content-type: text/plain;
        charset=gbk
content-transfer-encoding: base64
content-disposition: inline

agvsbg8=


--=-sinamail_alt_849bb6f96e7dc06cb99a08e3f9c84179
content-type: text/html;
        charset=gbk
content-transfer-encoding: base64
content-disposition: inline

pggxpmhlbgxvpc9omt4=


--=-sinamail_alt_849bb6f96e7dc06cb99a08e3f9c84179--

3.有附件的话,还会增加下面两种multipart类型

date: tue, 16 apr 2019 17:38:47 +0800
received: from shihan2@sopans.com([]) by  via http;
 tue, 16 apr 2019 17:38:47 +0800 (cst)
reply-to: shihan2@sopans.com
from: <shihan2@sopans.com>
to: shihan2@sopans.com
subject: =?gbk?b?ztlatlliytq=?=
mime-version: 1.0
x-priority: 3
x-messageid: 1555407527.4947.4232
x-originating-ip: []
x-mailer: sina webmail 4.0
x-sina-mid: 044d8eb6f6ef3f6fae1a32d8b0930f609000000000000002
content-type: multipart/mixed;
         boundary="=-sinamail_mix_fe895d50cd0d0669bb8a7eb8c697db19"

--=-sinamail_mix_fe895d50cd0d0669bb8a7eb8c697db19
content-type: multipart/alternative;
         boundary="=-sinamail_alt_f50efff67f5369967ea1a6c77020a1e7"

--=-sinamail_alt_f50efff67f5369967ea1a6c77020a1e7
content-type: text/plain;
        charset=gbk
content-transfer-encoding: base64
content-disposition: inline

agvsbg8=


--=-sinamail_alt_f50efff67f5369967ea1a6c77020a1e7
content-type: text/html; charset=gbk
content-transfer-encoding: base64
content-disposition: inline

pggxpmhlbgxvpc9omt4=


--=-sinamail_alt_f50efff67f5369967ea1a6c77020a1e7--

--=-sinamail_mix_fe895d50cd0d0669bb8a7eb8c697db19
content-type: application/octet-stream; name="=?gbk?b?ms5sb2c=?="
content-disposition: attachment; filename="=?gbk?b?ms5sb2c=?="
content-transfer-encoding: base64

mxwyntaguelqruxjtklorw0k


--=-sinamail_mix_fe895d50cd0d0669bb8a7eb8c697db19--

下面的代码是php组合mime邮件协议的类库

<?php
/**
 * rfc 822: cr lf
 * character "cr":hex value 0d
 * character "lf":hex value 0a
 * @var string
 */
define("crlf", "\r\n");

/**
 * rfc 2822: 2.1.1. line length limits
 * @var int
 */
define("mime_line_length_limit", 76);

class mimemail
{

    /**
     * the charset of the email
     * @var string
     */
    var $_mail_charset = 'gbk';
    var $_mail_text_charset = 'gbk';
    /**
     * the subject of the email
     * @var string
     */
    var $_mail_subject = '';
    /**
     * the from address including display-name of the email
     * @var string
     */
    var $_mail_from = '';
    /**
     * just keep the address of from
     *
     * @var string
     */
    var $_mail_from_addr = '';
    /**
     * the sender address  of the email
     * @var string
     */
    var $_mail_sender = '';
    /**
     * the to address list of the email
     * @var string
     */
    var $_mail_to = '';
    /**
     * the cc address list of the email
     * @var string
     */
    var $_mail_cc = '';
    /**
     * the bcc address list of the email
     * @var string
     */
    var $_mail_bcc = '';
    /**
     * the priority of the email
     * @var int, default 3
     */
    var $_mail_priority = 3;
    /**
     * need notification or not
     * @var string
     */
    var $_mail_needreply = false;
    /**
     * 回复地址
     * @var <string>
     */
    var $_mail_replyto = '';
    /**
     * notification address of the email
     * @var string
     */
    var $_mail_notificationto = '';
    /**
     * message id
     * @var string
     */
    var $_mail_messageid = '';
    /**
     * the text body of the email
     * @var string
     */
    var $_mail_textbody = '';
    /**
     * the html body of the email
     * @var string
     */
    var $_mail_htmlbody = '';
    var $_mail_bodytype = '';
    /**
     * the default body content-type
     * @var string
     */
    var $_mail_type = '';
    /**
     * the header of the email
     * @var string
     */
    var $_mail_header = '';
    /**
     * the body of the email
     * @var string
     */
    var $_mail_body = '';
    /**
     * 	附件信息数组(附件所在路径、附件名称、附件类型)
     */
    var $aattachments = array();
    /**
     * the encode attachments of the email
     * @var array
     */
    var $_mail_subpart_attachments = array();
    /**
     * the attachments  index of the email
     * @var array
     */
    var $_mail_attachments_index = 0;
    /**
     * count of embedded attachments
     * @var int
     */
    var $_mail_embedded_count = 0;
    /**
     * the boundary for 'multipart/mixed' type
     * @var string
     */
    var $_mail_boundary_mix = '';
    /**
     * the boundary for 'multipart/related'type
     * @var string
     */
    var $_mail_boundary_rel = '';
    /**
     * the boundary for 'multipart/alternative' type
     * @var array
     */
    var $_mail_boundary_alt = '';
    /**
     * 用户自定义邮件头
     *
     * @var array
     */
    var $_mail_userheaders = array();
    var $mime_types = array(
        'gif' => 'image/gif',
        'jpg' => 'image/jpeg',
        'jpeg' => 'image/jpeg',
        'jpe' => 'image/jpeg',
        'bmp' => 'image/bmp',
        'png' => 'image/png',
        'tif' => 'image/tiff',
        'tiff' => 'image/tiff',
        'swf' => 'application/x-shockwave-flash',
        'doc' => 'application/msword',
        'xls' => 'application/vnd.ms-excel',
        'ppt' => 'application/vnd.ms-powerpoint',
        'pdf' => 'application/pdf',
        'ps' => 'application/postscript',
        'eps' => 'application/postscript',
        'rtf' => 'application/rtf',
        'bz2' => 'application/x-bzip2',
        'gz' => 'application/x-gzip',
        'tgz' => 'application/x-gzip',
        'tar' => 'application/x-tar',
        'zip' => 'application/zip',
        'html' => 'text/html',
        'htm' => 'text/html',
        'txt' => 'text/plain',
        'css' => 'text/css',
        'js' => 'text/javascript',
        'eml' => 'message/rfc822'
    );

    var $_mail_clientip = '';

    /**
     * mimemail 构造函数
     *
     */
    function mimemail()
    {
        $this->_mail_messageid = sprintf('%s.%s', microtime(true), getmypid());
        $this->_mail_boundary_mix = "=-sinamail_mix_" . md5(uniqid(rand(), true));
        $this->_mail_boundary_rel = "=-sinamail_rel_" . md5(uniqid(rand(), true));
        $this->_mail_boundary_alt = "=-sinamail_alt_" . md5(uniqid(rand(), true));
        //$this->_mail_sended_index = 0 ;
    }

    /**
     * get message id
     *
     * @return string
     */
    function getmessageid()
    {
        return $this->_mail_messageid;
    }

    function convenc($s, $charset = 'gbk')
    {
        if ($charset == 'utf-8') {
            return array($s, 'utf-8');
        }

        if ($charset == 'gbk' && preg_match('/[^\x00-\x7f\x{3000}-\x{303f}\x{4e00}-\x{9fff}\x{ff00}-\x{ffef}]/u', $s)) {
            return array($s, 'utf-8');
        }

        $es = mb_convert_encoding($s, $charset, 'utf-8');
        if ($es === false) {
            return array($s, 'utf-8');
        } else {
            return array($es, $charset);
        }
    }

    function getclientip()
    {
        if (!$this->_mail_clientip) {
            $ip = isset($_server['http_x_forwarded_for']) ? $_server['http_x_forwarded_for'] : '';
            if (!$ip) {
                $ip = isset($_server['remote_addr']) ? $_server['remote_addr'] : '';
            }

            $a = explode('|', str_replace(',', '|', $ip));
            $this->_mail_clientip = trim($a[0]);
        }
        return $this->_mail_clientip;
    }

    function setclientip($ip)
    {
        $this->_mail_clientip = $ip;
    }

    /**
     * 取得用户自定义邮件头
     *
     * @param string $name
     * @return mixed
     */
    function getuserheader($name = '')
    {
        if (!$name) {
            return $this->_mail_userheaders;
        }

        return (isset($this->_mail_userheaders[$name]) ? $this->_mail_userheaders[$name] : false);
    }

    /**
     * 设置用户自定义邮件头
     *
     * @param mixed $value
     * @param string $name
     */
    function setuserheader($value, $name = '')
    {
        $d = array();
        if ($name == '') {
            if (is_array($value)) {
                $d = $value;
            } else {
                return;
            }
        } else {
            $d[$name] = $value;
        }

        foreach ($d as $k => $v) {
            if (is_scalar($v)) {
                $this->_mail_userheaders[$k] = $v;
            }
        }
    }

    /**
     * 设置邮件主题
     * @param string $subject 邮件主题
     *
     */
    function setsubject($subject)
    {
        if (!is_null($subject)) {
            if (!$this->isbig($subject)) {
                $this->_mail_subject = $subject;
            } else {
                list($subject, $charset) = $this->convenc($subject);
                $this->_mail_subject
                        = '=?' . $charset . '?b?' . base64_encode($subject) . '?=';
            }
        }
    }

    /**
     * 设置真实发信地址
     *
     * @param string $sender
     */
    function setsender($sender)
    {
        $this->_mail_sender = $sender;
    }

    /**
     * 设置发件人
     * @param string $from 发件人邮件地址
     * 	@param string $nickname 发件人昵称
     *
     */
    function setfrom($from, $nickname = '')
    {
        $this->_mail_from_addr = $from;
        if ('' == $nickname) {
            $this->_mail_from = '<' . $from . '>';
        } else {
            if ($this->isbig($nickname)) {
                list($nickname, $charset) = $this->convenc($nickname);

                $this->_mail_from = sprintf("\"=?%s?b?%s?=\" <%s>", $charset, base64_encode($nickname), $from);
            } else {
                $this->_mail_from = '"' . $nickname . '" <' . $from . '>';
            }
        }
    }

    /**
     * 设置收件人邮件列表
     * @param string $to 收件人邮件地址
     *
     */
    function setto($mail_to)
    {
        if (!is_null($mail_to)) {
            list($mail_to, $charset) = $this->convenc($mail_to);
            $this->_mail_to = $this->_encodeaddr($mail_to, $charset);
        }
    }

    /**
     * 设置抄送邮件列表
     * @param string $mail_cc 抄送邮件地址列表
     *
     */
    function setcc($mail_cc)
    {
        if (!is_null($mail_cc)) {
            list($mail_cc, $charset) = $this->convenc($mail_cc);
            $this->_mail_cc = $this->_encodeaddr($mail_cc, $charset);
        }
    }

    /**
     * 设置密送邮件列表
     * @param string $mail_bcc 密送邮件地址列表
     *
     */
    function setbcc($mail_bcc)
    {
        if (!is_null($mail_bcc)) {
            list($mail_bcc, $charset) = $this->convenc($mail_bcc);
            $this->_mail_bcc = $this->_encodeaddr($mail_bcc, $charset);
        }
    }

    /**
     * 设置邮件正文类型
     * @param string $text_type 邮件正文类型
     *
     */
    function setbodytype($text_type)
    {
        if ($text_type == 'html')
            $this->_mail_bodytype = $text_type;
        else
            $this->_mail_bodytype = "plain";
    }

    /**
     * 设置邮件优先级别
     * @param string $priority 邮件优先级别
     *
     */
    function setpriority($priority = 3)
    {
        $priority = !is_null($priority) ? $priority : 3;
        $this->_mail_priority = $priority;
    }

    /**
     * 设置邮件优先级别
     * @param string $isneedreply 是否需要读信回执
     * @param string $addr_notificationto 回执邮件地址
     */
    function setnotificationto($isneedreply = false, $addr_notificationto = '')
    {
        if ($isneedreply == true) {
            $this->_mail_needreply = $isneedreply;

            if (empty($addr_notificationto))
                $this->_mail_notificationto = $this->_mail_sender;
            else
                $this->_mail_notificationto = $addr_notificationto;
        }
    }

    /**
     * 设置邮件回复信息
     * @param <string> $replyto
     */
    function setreplyto($replyto)
    {
        $this->_mail_replyto = $replyto;
    }

    /**
     * 添加文本格式正文
     * @param string $text 文本格式正文
     */
    function addtextbody($text)
    {
        list($text, $charset) = $this->convenc($text, $this->_mail_text_charset);
        if ($charset != $this->_mail_text_charset) {
            $this->_mail_textbody = mb_convert_encoding($this->_mail_textbody, $charset, $this->_mail_text_charset);
            $this->_mail_text_charset = $charset;
        }
        $this->_mail_textbody .= $text;
    }

    /**
     * 添加html格式正文
     * @param string $html html格式正文
     */
    function addhtmlbody($html)
    {
        list($html, $charset) = $this->convenc($html, $this->_mail_charset);
        if ($charset != $this->_mail_charset) {
            $this->_mail_htmlbody = mb_convert_encoding($this->_mail_htmlbody, $charset, $this->_mail_charset);
            $this->_mail_charset = $charset;
        }
        $this->_mail_htmlbody .= $html;
    }

    function & getsendmailtext($to = null)
    {
        $msg = '';
        if (!empty($this->_mail_userheaders['sina-sendseparate'])) {
            if ($to) {
                $header = str_replace('<{$_mail_to}>', $this->_splitaddrlist($to), $this->_mail_header);
            } else {
                $header = str_replace('<{$_mail_to}>', $this->_splitaddrlist($this->_mail_to), $this->_mail_header);
            }
            $msg = $header . crlf . crlf . $this->_mail_body;
        } else {
            $msg = $this->_mail_header . crlf . crlf . $this->_mail_body;
        }
        return $msg;
    }

    /*
     * 	生成邮件header
     * @param string $mailcontenttype 邮件content-type
     * 	@return string mailheader
     */

    function _buildheader($mailcontenttype)
    {
        //$this->_mail_header = 'return-path: ' . $this->_mail_sender . crlf;
        $this->_mail_header =
                'date: ' . date("d, d m y h:i:s") . " +0800 " . crlf;

        $this->_mail_header .=
                'received: from ' . $this->_mail_sender . '([' . $this->getclientip() . ']) by '
                . $_server['http_host'] . ' via http;' . crlf
                . ' ' . date("d, d m y h:i:s") . " +0800 (cst)" . crlf;

        $replyto = (!empty($this->_mail_replyto)) ? $this->_mail_replyto : $this->_mail_sender;
        $this->_mail_header .= 'reply-to: ' . $replyto . crlf;

        if (strcasecmp($this->_mail_sender, $this->_mail_from_addr) != 0) {
            $this->_mail_header .= 'sender: ' . $this->_mail_sender . crlf;
        }

        if (!is_null($this->_mail_from))
            $this->_mail_header .=
                    "from: " . $this->_splitaddrlist($this->_mail_from) . crlf;

        if (!empty($this->_mail_userheaders['sina-sendseparate'])) {
            $this->_mail_header .= 'to: <{$_mail_to}>' . crlf;
        } else {
            if (!is_null($this->_mail_to))
                $this->_mail_header .=
                        "to: " . $this->_splitaddrlist($this->_mail_to) . crlf;
        }

        if (!empty($this->_mail_cc))
            $this->_mail_header .=
                    "cc: " . $this->_splitaddrlist($this->_mail_cc) . crlf;

        if (!empty($this->_mail_bcc))
            $this->_mail_header .= "bcc: " . $this->_splitaddrlist($this->_mail_bcc) . crlf;

        if (!is_null($this->_mail_subject))
            $this->_mail_header .= "subject: " . $this->_mail_subject . crlf;

        $this->_mail_header .= "mime-version: 1.0" . crlf;
        $this->_mail_header .= "x-priority: " . $this->_mail_priority . crlf;

        if ($this->_mail_needreply == true)
            $this->_mail_header .=
                    "disposition-notification-to: " . $this->_mail_notificationto . crlf;

        $this->_mail_header .= 'x-messageid: ' . $this->_mail_messageid . crlf;

        $this->_mail_header .= 'x-originating-ip: [' . $_server["server_addr"] . "]" . crlf;
        $this->_mail_header .= "x-mailer: sina webmail 4.0" . crlf;

        foreach ($this->_mail_userheaders as $k => $v) {
            $hn = str_replace(' ', '-', ucwords(str_replace('-', ' ', $k)));
            $this->_mail_header .= "x-$hn: $v" . crlf;
        }

        $this->_mail_header .= $mailcontenttype;
    }

    /*
     * 	生成邮件体
     * 	@return bool 成功返回0,失败返回错误代码
     *
     */

    function buildbody()
    {

        /*
          $b_attachments 		= ($this->_mail_attachments	> 0 )			? true : false;
          $b_imgattachments = (count($this->attachments_img) > 0)	? true : false;
          $b_htmlbody       = !empty($this->_htmlbody)             ? true : false;
          $b_textbody       = (!$html and !empty($this->_txtbody)) ? true : false;
         */

        if (count($this->aattachments) > 0) {
            foreach ($this->aattachments as $a_attfile) {
                if (!$this->_getattachment($a_attfile['attfilepath'], $a_attfile['attname'], $a_attfile['atttype'], $a_attfile['attembedded'])) {
                    return false;
                }
            }
        }

        switch ($this->_parseelements()) {
            case 1:  //text/plain
                $this->_buildheader("content-type: text/plain; charset=$this->_mail_text_charset\ncontent-transfer-encoding: base64");
                $this->_mail_body = $this->_gettextmailbody();
                break;

            case 3:  //text/plain && text/html
                $this->_buildheader("content-type: multipart/alternative;\n\t boundary=\"$this->_mail_boundary_alt\"");
                $this->_mail_body = "--" . $this->_mail_boundary_alt . crlf;
                $this->_mail_body .=
                        "content-type: text/plain;\n\tcharset=$this->_mail_text_charset" . crlf;

                $this->_mail_body .= "content-transfer-encoding: base64" . crlf;
                $this->_mail_body .= "content-disposition: inline" . crlf . crlf;
                $this->_mail_body .= $this->_gettextmailbody() . crlf . crlf;
                $this->_mail_body .= "--" . $this->_mail_boundary_alt . crlf;

                $this->_mail_body .=
                        "content-type: text/html; \n\tcharset=$this->_mail_charset" . crlf;
                $this->_mail_body .= "content-transfer-encoding: base64" . crlf;
                $this->_mail_body .= "content-disposition: inline" . crlf . crlf;
                $this->_mail_body .= $this->_gethtmlmailbody() . crlf . crlf;
                $this->_mail_body .= "--" . $this->_mail_boundary_alt . "--" . crlf;
                break;

            case 5:  // text/plain && attachments
                $this->_buildheader("content-type: multipart/mixed;\n\t boundary=\"$this->_mail_boundary_mix\"");
                $this->_mail_body = "--" . $this->_mail_boundary_mix . crlf;
                $this->_mail_body .=
                        "content-type: text/plain;\n\tcharset=$this->_mail_text_charset" . crlf;
                $this->_mail_body .= "content-transfer-encoding: base64" . crlf;
                $this->_mail_body .= "content-disposition: inline" . crlf . crlf;
                $this->_mail_body .= $this->_gettextmailbody() . crlf . crlf;

                foreach ($this->_mail_subpart_attachments as $value) {
                    $this->_mail_body .= "--" . $this->_mail_boundary_mix . crlf;
                    $this->_mail_body .=
                            "content-type: " . $value['type'] . "; name=\"" . $value['name'] . "\"" . crlf;
                    $this->_mail_body .=
                            "content-disposition: attachment; filename=\"" . $value['name'] . "\"" . crlf;
                    if ($value['type'] == 'message/rfc822') {
                        $this->_mail_body .= "content-transfer-encoding: 8bit" . crlf . crlf;
                    } else {
                        $this->_mail_body .= "content-transfer-encoding: base64" . crlf . crlf;
                    }
                    $this->_mail_body .= $value['content'] . crlf . crlf;
                }

                $this->_mail_body .= "--" . $this->_mail_boundary_mix . "--" . crlf;
                break;

            case 7:  //text/plain && text/html && attachment
                $this->_buildheader("content-type: multipart/mixed;\n\t boundary=\"$this->_mail_boundary_mix\"");
                $this->_mail_body = "--" . $this->_mail_boundary_mix . crlf;
                $this->_mail_body .= "content-type: multipart/alternative;\n\t boundary=\"$this->_mail_boundary_alt\"" . crlf . crlf;
                $this->_mail_body .= "--" . $this->_mail_boundary_alt . crlf;
                $this->_mail_body .= "content-type: text/plain;\n\tcharset=$this->_mail_text_charset" . crlf;
                $this->_mail_body .= "content-transfer-encoding: base64" . crlf;
                $this->_mail_body .= "content-disposition: inline" . crlf . crlf;
                $this->_mail_body .= $this->_gettextmailbody() . crlf . crlf;
                $this->_mail_body .= "--" . $this->_mail_boundary_alt . crlf;

                $this->_mail_body .= "content-type: text/html; charset=$this->_mail_charset" . crlf;
                $this->_mail_body .= "content-transfer-encoding: base64" . crlf;
                $this->_mail_body .= "content-disposition: inline" . crlf . crlf;
                $this->_mail_body .= $this->_gethtmlmailbody() . crlf . crlf;
                $this->_mail_body .= "--" . $this->_mail_boundary_alt . "--" . crlf . crlf;

                foreach ($this->_mail_subpart_attachments as $value) {
                    $this->_mail_body .= "--" . $this->_mail_boundary_mix . crlf;
                    $this->_mail_body .= "content-type: " . $value['type'] . "; name=\"" . $value['name'] . "\"" . crlf;
                    $this->_mail_body .= "content-disposition: attachment; filename=\"" . $value['name'] . "\"" . crlf;
                    if ($value['type'] == 'message/rfc822') {
                        $this->_mail_body .= "content-transfer-encoding: 8bit" . crlf . crlf;
                    } else {
                        $this->_mail_body .= "content-transfer-encoding: base64" . crlf . crlf;
                    }
                    $this->_mail_body .= $value['content'] . crlf . crlf;
                }
                $this->_mail_body .= "--" . $this->_mail_boundary_mix . "--" . crlf;
                break;

            case 11:
                $this->_buildheader("content-type: multipart/related; type=\"multipart/alternative\";\n\t boundary=\"$this->_mail_boundary_rel\"");
                $this->_mail_body = "--" . $this->_mail_boundary_rel . crlf;
                $this->_mail_body .= "content-type: multipart/alternative;\n\t boundary=\"$this->_mail_boundary_alt\"" . crlf . crlf;
                $this->_mail_body .= "--" . $this->_mail_boundary_alt . crlf;
                $this->_mail_body .= "content-type: text/plain;\n\tcharset=$this->_mail_text_charset" . crlf;
                $this->_mail_body .= "content-transfer-encoding: base64" . crlf;
                $this->_mail_body .= "content-disposition: inline" . crlf . crlf;
                $this->_mail_body .= $this->_gettextmailbody() . crlf . crlf;
                $this->_mail_body .= "--" . $this->_mail_boundary_alt . crlf;

                $this->_mail_body .= "content-type: text/html; charset=$this->_mail_charset" . crlf;
                $this->_mail_body .= "content-transfer-encoding: base64" . crlf;
                $this->_mail_body .= "content-disposition: inline" . crlf . crlf;
                $this->_mail_body .= $this->_gethtmlmailbody() . crlf . crlf;
                $this->_mail_body .= "--" . $this->_mail_boundary_alt . "--" . crlf . crlf;

                foreach ($this->_mail_subpart_attachments as $value) {
                    if ($value['embedded']) {
                        $this->_mail_body .= "--" . $this->_mail_boundary_rel . crlf;
                        $this->_mail_body .= "content-id: <" . $value['embedded'] . ">" . crlf;
                        $this->_mail_body .= "content-type: " . $value['type'] . "; name=\"" . $value['name'] . "\"" . crlf;
                        $this->_mail_body .= "content-disposition: attachment; filename=\"" . $value['name'] . "\"" . crlf;
                        $this->_mail_body .= "content-transfer-encoding: base64" . crlf . crlf;
                        $this->_mail_body .= $value['content'] . crlf . crlf;
                    }
                }
                $this->_mail_body .= "--" . $this->_mail_boundary_rel . "--" . crlf;
                break;

            case 15:
                $this->_buildheader("content-type: multipart/mixed;\n\t boundary=\"$this->_mail_boundary_mix\"");
                $this->_mail_body .= "--" . $this->_mail_boundary_mix . crlf;

                $this->_mail_body .= "content-type: multipart/related; type=\"multipart/alternative\"; boundary=\"$this->_mail_boundary_rel\"" . crlf . crlf;
                $this->_mail_body .= "--" . $this->_mail_boundary_rel . crlf;

                $this->_mail_body .= "content-type: multipart/alternative;\n\t boundary=\"$this->_mail_boundary_alt\"" . crlf . crlf;
                $this->_mail_body .= "--" . $this->_mail_boundary_alt . crlf;

                $this->_mail_body .= "content-type: text/plain; charset=$this->_mail_text_charset" . crlf;
                $this->_mail_body .= "content-transfer-encoding: base64" . crlf;
                $this->_mail_body .= "content-disposition: inline" . crlf . crlf;
                $this->_mail_body .= $this->_gettextmailbody() . crlf . crlf;
                $this->_mail_body .= "--" . $this->_mail_boundary_alt . crlf;

                $this->_mail_body .= "content-type: text/html; charset=$this->_mail_charset" . crlf;
                $this->_mail_body .= "content-transfer-encoding: base64" . crlf;
                $this->_mail_body .= "content-disposition: inline" . crlf . crlf;
                $this->_mail_body .= $this->_gethtmlmailbody() . crlf . crlf;
                $this->_mail_body .= "--" . $this->_mail_boundary_alt . "--" . crlf . crlf;

                foreach ($this->_mail_subpart_attachments as $value) {
                    if ($value['embedded']) {
                        $this->_mail_body .= "--" . $this->_mail_boundary_rel . crlf;
                        $this->_mail_body .= "content-id: <" . $value['embedded'] . ">" . crlf;
                        $this->_mail_body .= "content-type: " . $value['type'] . "; name=\"" . $value['name'] . "\"" . crlf;
                        $this->_mail_body .= "content-disposition: attachment; filename=\"" . $value['name'] . "\"" . crlf;
                        $this->_mail_body .= "content-transfer-encoding: base64" . crlf . crlf;
                        $this->_mail_body .= $value['content'] . crlf . crlf;
                    }
                }
                $this->_mail_body .= "--" . $this->_mail_boundary_rel . "--" . crlf . crlf;

                foreach ($this->_mail_subpart_attachments as $value) {
                    if (!$value['embedded']) {
                        $this->_mail_body .= "--" . $this->_mail_boundary_mix . crlf;
                        $this->_mail_body .= "content-type: " . $value['type'] . "; name=\"" . $value['name'] . "\"" . crlf;
                        $this->_mail_body .= "content-disposition: attachment; filename=\"" . $value['name'] . "\"" . crlf;
                        //$this->_mail_body .= "content-transfer-encoding: base64" . crlf . crlf;
                        if ($value['type'] == 'message/rfc822') {
                            $this->_mail_body .= "content-transfer-encoding: 8bit" . crlf . crlf;
                        } else {
                            $this->_mail_body .= "content-transfer-encoding: base64" . crlf . crlf;
                        }
                        $this->_mail_body .= $value['content'] . crlf . crlf;
                    }
                }
                $this->_mail_body .= "--" . $this->_mail_boundary_mix . "--" . crlf;
                break;

            default:
                return false;
        }
        //$this->sended_index++;
        return true;
    }

    /*
     * 	分析content-type
     * @param string $mailcontenttype 邮件content-type
     * 	@return string mailheader
     */

    function _parseelements()
    {
        if ($this->_mail_bodytype == "html") {
            $this->_mail_type = 3;
            if (!empty($this->mail_html)) {
                if (empty($this->mail_text))
                    $this->mail_text = $this->htmltotext($this->mail_html);
            }
        }
        else
            $this->_mail_type = 1;

        if ($this->_mail_attachments_index != 0) {
            if ($this->_mail_type == 3 && $this->_mail_embedded_count > 0) {
                $this->_mail_type = $this->_mail_type + 8;
                if ((count($this->aattachments) - $this->_mail_embedded_count) >= 1) {
                    $this->_mail_type = $this->_mail_type + 4;
                }
            } else if (count($this->aattachments) > 0) {
                $this->_mail_type = $this->_mail_type + 4;
            }
        }
        return $this->_mail_type;
    }

    /**
     * 添加附件
     * @param string $attfile 附件文件绝对路径
     * @param string $attname 附件名称
     * @param string $attfiletype 附件文件类型
     * @param bool   $attembedded 附件是否为嵌入
     * 	@return 成功 0,失败 错误代码
     */
    function addattachment($sattfilepath, $sattname, $satttype='', $sattembedded = false)
    {
        if (is_null($sattfilepath)) {
            return;
        }

        $embedded = false;
        if ($sattembedded) {
            $this->_mail_embedded_count++;
            $embedded = sprintf('part%s.%s', $this->_mail_embedded_count, $this->_mail_messageid);
        }

        $this->aattachments[$this->_mail_attachments_index] = array(
            'attfilepath' => $sattfilepath,
            'attname' => $sattname,
            'atttype' => $satttype,
            'attembedded' => $embedded
        );
        $this->_mail_attachments_index++;
    }

    /**
     * 获取附件subpart信息
     * @param string $attfile 附件文件绝对路径
     * @param string $attname 附件名称
     * @param string $attfiletype 附件文件类型
     * @param int    $attembedded 附件嵌入id
     * 	@return 成功 0,失败 错误代码
     */
    function _getattachment($attfile, $attname, $attfiletype = "", $attembedded)
    {
        
        $content = file_get_contents($attfile);
        if ($content !== false) {
            list($attname, $charset) = $this->convenc($attname);
            $attfiletype = empty($attfiletype) ? $this->_getmimetype($attname) : $attfiletype;
            if ($attfiletype == 'message/rfc822') {
                $this->_mail_subpart_attachments[] = array(
                    'content' => $content,
                    'name' => '=?' . $charset . '?b?' . base64_encode($attname) . '?=',
                    'type' => $attfiletype,
                    'embedded' => false
                );
            } else {
                $this->_mail_subpart_attachments[] = array(
                    'content' => chunk_split(base64_encode($content), mime_line_length_limit, crlf),
                    'name' => '=?' . $charset . '?b?' . base64_encode($attname) . '?=',
                    'type' => $attfiletype,
                    'embedded' => $attembedded
                );
            }
            return true;
        } else {
            return false;
        }
    }

    /**
     * 	将文本格式正文按照rfc规范编码并拆分成行
     * 	@param	string
     */
    function _gettextmailbody()
    {
        if (isset($this->_mail_textbody) && !is_null($this->_mail_textbody))
            return chunk_split(
                    base64_encode($this->_mail_textbody), mime_line_length_limit, crlf);
        else
            return '';
    }

    /**
     * 将嵌入附件的标记替换为实际的content-id
     *
     * @param string $body
     * @return string
     */
    function _replaceembedded($body)
    {
        foreach ($this->aattachments as $att) {
            if (!$att['attembedded']) {
                continue;
            }

            $search = '__cid__' . md5($att['attfilepath']);
            $repl = 'cid:' . $att['attembedded'];
            $body = str_replace($search, $repl, $body);
        }
        return $body;
    }

    /**
     * 	将html格式正文按照rfc规范编码并拆分成行
     * 	@param	string
     */
    function _gethtmlmailbody()
    {
        if (isset($this->_mail_htmlbody) && !is_null($this->_mail_htmlbody)) {
            if ($this->_mail_embedded_count > 0) {
                $this->_mail_htmlbody = $this->_replaceembedded($this->_mail_htmlbody);
            }
            return chunk_split(
                    base64_encode($this->_mail_htmlbody), mime_line_length_limit, crlf);
        } else {
            return '';
        }
    }

    /**
     * private
     * 	获取附件类型
     * @param string $attname 附件名称
     */
    function _getmimetype($attname)
    {
        $ext_array = explode(".", $attname);
        if (($last = count($ext_array) - 1) != 0) {
            $ext = strtolower($ext_array[$last]);
            if (isset($this->mime_types[$ext]))
                return $this->mime_types[$ext];
        }
        return "application/octet-stream";
    }

    /**
     * 按照rfc规范将邮件地址列表拆分成行
     * 	@param string $inputaddr 邮件地址列表
     * @return string 规范后的邮件地址列表
     */
    function _splitaddrlist($inputaddr)
    {
        if (is_null($inputaddr) || mime_line_length_limit > strlen($inputaddr))
            return $inputaddr;
        else {
            $a_splitaddr = explode(",", $inputaddr);
            $curlen = 0;
            $outputaddr = '';
            foreach ($a_splitaddr as $key => $address) {
                $curlen += strlen($address);

                if (mime_line_length_limit < $curlen) {
                    $outputaddr .= crlf . ' ' . $address . ",";
                    $curlen = strlen($address);
                } else {
                    $outputaddr .= $address . ",";
                }
            }
            return $outputaddr;
        }
    }

    /**
     * encode addlist for mime header
     * @param string $addr_str 邮件地址列表
     *
     */
    function _encodeaddr($addr_str, $charset = 'gbk')
    {
        $addr_ret = '';

        $addr_str = mb_ereg_replace(mb_convert_encoding(',', $charset, 'utf-8'), ',', $addr_str, $charset);
        $addrs = $this->_splitaddressstr($addr_str);
        foreach ($addrs as $key => $addr) {
            $addr = trim($addr);
            if ($key != 0)
                $addr_ret .= ', ';

            if (preg_match('/(.*)<(.*)>$/', $addr, $addr_split)) {

                $addr_name = trim($addr_split[1]);
                $addr_name = trim($addr_name, '"');
                $addr_mail = trim($addr_split[2]);
                mb_internal_encoding($charset);

                if (!self::isbig($addr_name)) {
                    $addr_ret .= '"' . $addr_name . '" <' . $addr_mail . '>';
                } else {
                    $addr_ret .= '=?' . $charset . '?b?' . base64_encode($addr_name) . '?= <' . $addr_mail . '>';
                }
            }
            else
                $addr_ret .= $addr;
        }
        return $addr_ret;
    }

    function _splitaddressstr($s)
    {
        $ls = array();
        $inquote = false;
        $item = '';
        for ($i = 0, $n = strlen($s); $i < $n; ++$i) {
            $ch = $s[$i];
            if ($ch == '"') {
                if (!$inquote) {
                    $inquote = true;
                } else {
                    $inquote = false;
                }
            } elseif ($ch == ',' || $ch == ';') {
                if (!$inquote) {
                    if (isset($item[0])) {
                        array_push($ls, $item);
                        $item = '';
                    }
                } else {
                    $item .= $ch;
                }
            } else {
                $item .= $ch;
            }
        }

        if (isset($item[0])) {
            array_push($ls, $item);
        }

        return $ls;
    }

    /**
     * 将html格式转换为text
     * @param string $html
     * 	@return string 转换后text字符串
     */
    function htmltotext($html)
    {
        if (!strlen($html))
            return '';

        $search = array("'<br[^>]*?>'si");
        $replace = array("\n");
        $txt = preg_replace($search, $replace, $html);

        $txt = strip_tags($txt);
        return htmlspecialchars_decode($txt);
    }

    /**
     * 检查是否是大字符集
     *
     * @param string type $string
     * @return boolean
     */
    function isbig($string)
    {
        for ($i = 0; $i < strlen($string); $i++) {
            if (ord($string[$i]) > 127) {
                return true;
            }
        }
        return false;
    }

}
$html='<h1>hello</h1>';
$text=strip_tags($html);

$mime=new mimemail();
//增加一个邮件头
$mime->setuserheader('044d8eb6f6ef3f6fae1a32d8b0930f609000000000000002', 'sina-mid');
$mime->setsender("shihan2@sopans.com");
$mime->setfrom("shihan2@sopans.com");
$mime->setto("shihan2@sopans.com");
$mime->setsubject("我来测试");
$mime->setbodytype('html');

$mime->addhtmlbody($html);
$mime->addtextbody($text);
$mime->addattachment("d:/phpserver/www/test/1.log","1.log","");

$mime->buildbody();
$mail=$mime->getsendmailtext();

echo $mail;
//file_put_contents("2.eml",$mail);