使用PHP起草带有附件的IMAP电子邮件


Drafting IMAP emails with an attachment using PHP

我正在尝试添加一个附件到我起草的电子邮件,但似乎不能让它工作。我试着在这里和这里效仿,但没有成功。

到目前为止我能做的是:

  1. 连接到Exchange服务器
  2. 打开邮箱
  3. 起草html电子邮件
  4. 将电子邮件附加到邮箱,并使其正确呈现html。(当使用text/html作为内容类型时)。使用其他任何方式都将html显示为明文。

作为附加说明,在起草后,电子邮件被附加到Exchange 2010服务器上的邮箱中,并通过Outlook 2010查看然后发送。

下面是我的mailer类和起草邮件的代码。

mailer.php

<?php
class mailer
{
    const USER      =   'user';
    const PASSWORD  =   'pass';
    const MAILBOX   =   '{conn}DRAFTS';
    // STRING ORDER: $content-type . $from . $to . $cc . $subject . "'r'n'r'n" . $message
    public $message;
    public $imap_conn;
    public $boundary;
    function __construct()
    {
        // Open the message property so we can start appending strings.
        $this->message = '';
        // Open the IMAP connection
        $this->imap_conn = imap_open(self::MAILBOX,self::USER,self::PASSWORD);
    }
    public function content_type($string_type)
    {
        $this->message .= "Content-type:{$string_type}'r'n";
    }
    public function from($string_from)
    {
        $this->message .= "From:{$string_from}'r'n";
    }
    public function to($string_to)
    {
        $this->message .= "To:{$string_to}'r'n";
    }
    public function cc($string_cc)
    {
        $this->message .= "Cc:{$string_cc}'r'n";
    }
    public function mime($float_mime_version)
    {
        $this->message .= "MIME-Version:{$float_mime_version}'r'n";
    }
    public function subject($string_subject)
    {
        $this->message .= "Subject:{$string_subject}'r'n'r'n";
    }
    public function message($string_message)
    {
        $this->message .= "{$string_message}'r'n";
    }
    public function set_boundary($string_boundary)
    {
        $this->boundary = $string_boundary;
    }
    public function append()
    {
        imap_append($this->imap_conn,self::MAILBOX,$this->message,"''Draft");
        imap_close($this->imap_conn);
    }
}
?>

准则草案
// A random hash used for the boundary
$rh = md5(date('c',time()));
$data = chunk_split(base64_encode('Testing'));

$m = new mailer;
$m->set_boundary('--PHP-mixed-' . $rh);
$m->content_type('multipart/mixed; boundary="' . $m->boundary . '"');
$m->mime('1.0');
$m->from('from@mail.com');
$m->to('to@mail.com');
$m->cc('cc1@mail.com,cc2@mail.com');
$m->subject('A new email');
$m->message("
    {$m->boundary}
    Content-Type: text/html; charset='"utf-8'"
    Content-Transfer-Encoding: base64
    Testing my <b>HTML</b>
    </br>
    {$m->boundary}
    Content-Type: application/octet-stream; name='"test.txt'"
    Content-Transfer-Encoding: base64
    Content-Disposition: attachment; filename='"test.txt'"
    {$data}
    {$m->boundary}--
    "));
$m->append();

后面的

Content-type:multipart/mixed; boundary="--PHP-mixed-b408f941593cf92b5a8bd365abb4e64f"
MIME-Version:1.0
From:from@mail.com
To:to@mail.com
Cc:cc1@mail.com
Subject:New Message

            --PHP-mixed-b408f941593cf92b5a8bd365abb4e64f
            Content-Type: text/html; charset="utf-8"
            Content-Transfer-Encoding: "base64"
            My <b>html</b> content

            --PHP-mixed-b408f941593cf92b5a8bd365abb4e64f
            Content-Type: application/octet-stream; name="test.txt"
            Content-Transfer-Encoding: base64
            Content-Disposition: attachment; filename="test.txt"

            --PHP-mixed-b408f941593cf92b5a8bd365abb4e64f--

问题:如何通过IMAP将附件添加到PHP起草的电子邮件中?

答案:简而言之,问题出在两个地方。
  1. 换行符放置不当('r'n)。每个标题后面应该有一个换行符,每个节的结束标题后面应该有两个换行符。

  2. 不当边界。边界应该以——开头,后跟一个唯一的字符串。消息的结束边界应该以——(参见图2

  3. )开始和结束。
图1

Content-Type: text/html'r'n
Content-Encoding: base64'r'n'r'n
"Message text here."'r'n
图2

--unique
Content-Type: text/html'r'n
Content-Encoding: base64'r'n'r'n
HTML stuff here.'r'n
--unique
Content-Type: application/octet-stream'r'n
Content-Disposition: attachment; filename='"logs.csv'"'r'n
Content-Transfer-Encoding: base64'r'n'r'n
Attachment(s)'r'n
--unique--

我打算写一篇更深入的文章,因为我花了非常很长时间才把它写对。

了解到目前为止调试的更多信息将会很有帮助。文件是否读取成功?有东西送到邮箱了吗?它还可以帮助我在最后追加之前看到完整消息的输出。

我不知道这是否会解决它,但从我成功的代码和你的第二个例子中,你的消息应该有一个额外的文件名属性,并在引号中包装的值。

Content-Type: application/octet-stream; name="test.txt"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="test.txt"