获取附件 - imap_fetchbody()

时间:2011-11-07 13:13:02

标签: php imap

如何在电子邮件中提取附件?

$structure = imap_fetchstructure($this->stream, $this->msgno);
//print_r($structure);
if(isset($structure->parts)){
    foreach($structure->parts as $section => $part){
        if(isset($part->disposition)){
            if(strtolower($part->disposition) == 'attachment'){
                echo 'section = '.$section."\n";
                $body = imap_fetchbody($this->stream, $this->msgno, $section);

                $finfo = new finfo(FILEINFO_MIME);
                echo $finfo->buffer($body) . "\n";

                $file = Init::$dynamic['data_path'].$this->msgno.'_'.$part->dparameters[0]->value;

                imap_savebody($this->stream, $file, $this->msgno, $section);

                echo $finfo->file($file) . "\n";

                //print_r($body);
            }
        }
    }
}

返回的附件甚至没有接近正确的文件大小,返回的数据看起来像这样

ZHUga2VuZGVyIHZlbCBpa2tlIG5vZ2VuIHNvbSBlciB2ZWQgYXQgc3RhcnRlIGVnZW4gdmly
a3NvbWhlZCBlbGxlciBzb20gbGlnZSBlciBzdGFydGV0IG9wPyA6KQ0KDQpmb3JkaSBqZWcg
bmV0b3AgZXIgYmxldmV0IGbmcmRpZyBtZWQgYXQgbGF2ZSBldCD4a29ub21pc3lzdGVtIG1l
ZCBlbiByZXZpc29yIHNvbSBlciB1ZHZpa2xldCBtZWQgc+ZybGlndCBoZW5ibGlrIHDlIGl2
5nJrc+Z0dGVyZSBzb20gb2Z0ZSBpa2tlIGhhciBkZW4gc3RvcmUgaW5kc2lndCBpIPhrb25v
bWkgOik=

相同的文件即使是副本也具有相同的文件大小

4 个答案:

答案 0 :(得分:4)

我认为你的代码变得复杂。

您的问题是您没有获得编码数据

$body = imap_fetchbody($this->stream, $this->msgno, $part);
//$part=2 (first attachment file)
//$part=3 (second attachment file) ...

在获取该文件中的真实数据之前,请先查看

$coding = $structure->parts[$part]->encoding;
if ($coding == 0) {
    $body = imap_7bit($body);
} elseif ($coding == 1) {
    $body= imap_8bit($body);
} elseif ($coding == 2) {
    $body = imap_binary($body);
} elseif ($coding == 3) {
    $body = imap_base64($body);
} elseif ($coding == 4) {
    $body = imap_qprint($body);
} elseif ($coding == 5) {
    $body = $body;
}

所以你可以尝试打印出来:

echo $body;

注意:$ section是文件的一部分。

答案 1 :(得分:1)

你所拥有的是二进制数据的ASCII表示,使用称为base64的编码方案进行编码。完全收到字符串后,使用base64_decode访问二进制数据,通常用尾随=表示。

答案 2 :(得分:1)

$emailtop= imap_search($inbox,'SUBJECT "'.$word.'" SINCE "'.sinceDate.'" BEFORE "'.beforeDate.'"');



/* if any emails found, iterate through each email */
if($emailtop) {

    /* put the newest emails on top */
    //rsort($emails);
   //print_r($emails); //die;
    /* for every email... */
    foreach($emailtop as $email_number) 
    {
        echo "</br> emailtop".$email_number;

        $overview = imap_fetch_overview($inbox,$email_number,0);
        echo '</br><span class="subject">'.$overview[0]->subject.'</span> ';
         //echo  'ds</br><span class="subject">'.$overview[0]->subject.'</span> ';
         if (!file_exists($dateTime)) {
            mkdir($dateTime, 0777, true);
        }

         /* get mail structure */
        $structure = imap_fetchstructure($inbox, $email_number);

        $attachments = array();

        /* if any attachments found... */
        if(isset($structure->parts) && count($structure->parts)) 
        {
            echo "<pre>";print_r($structure->parts);

            for($i = 0; $i < count($structure->parts); $i++) 
            {
                if(isset($structure->parts[$i]->parts) && !empty($structure->parts[$i]->parts) && count($structure->parts[$i]->parts)>0)
                {
                    echo "</br> SubCategory".$email_number;
                    //echo "<pre>";print_r($structure->parts[$i]);
                    for($y = 0; $y < count($structure->parts[$i]->parts); $y++) 
                    {
                        echo "</br> SubCategory loop".$email_number;
                        //echo "<pre>";print_r($structure->parts[$i]->parts);
                        $attachments[$y] = array(
                        'is_attachment' => false,
                        'filename' => '',
                        'name' => '',
                        'attachment' => ''
                    );

                     //die;

                    if($structure->parts[$i]->parts[$y]->ifdparameters==1) 
                    {


                        foreach($structure->parts[$i]->parts[$y]->dparameters as $object) 
                        {

                            if(strtolower($object->attribute) == 'filename') 
                            {
                                $attachments[$y]['is_attachment'] = true;
                                $attachments[$y]['filename'] = $object->value;
                            }
                        }
                    }

                    if($structure->parts[$i]->parts[$y]->ifparameters) 
                    {
                        foreach($structure->parts[$i]->parts[$y]->parameters as $object) 
                        {
                            if(strtolower($object->attribute) == 'name') 
                            {
                                $attachments[$y]['is_attachment'] = true;
                                $attachments[$y]['name'] = $object->value;
                            }
                        }
                    }

                    if($attachments[$y]['is_attachment']) 
                    {
                        $attachments[$y]['attachment'] = imap_fetchbody($inbox, $email_number, ($i+1).'.'.($y+1));

                        /* 4 = QUOTED-PRINTABLE encoding */
                        if($structure->parts[$i]->parts[$y]->encoding == 3) 
                        { 
                            //echo "hi  ". $attachments[$y]['attachment']; die;

                            $attachments[$y]['attachment'] = base64_decode($attachments[$y]['attachment']);
                        }
                        /* 3 = BASE64 encoding */
                        elseif($structure->parts[$i]->parts[$y]->encoding == 4) 
                        { 

                            $attachments[$y]['attachment'] = quoted_printable_decode($attachments[$y]['attachment']);
                        }

                    }
                    }
                }
                else
                {
                    echo "</br> Single".$email_number;
                    $attachments[$i] = array(
                        'is_attachment' => false,
                        'filename' => '',
                        'name' => '',
                        'attachment' => ''
                    );

                     //die;
                    if($structure->parts[$i]->ifdparameters==1) 
                    {


                        foreach($structure->parts[$i]->dparameters as $object) 
                        {


                            if(strtolower($object->attribute) == 'filename') 
                            {
                                $attachments[$i]['is_attachment'] = true;
                                $attachments[$i]['filename'] = $object->value;
                            }
                        }
                    }

                    if($structure->parts[$i]->ifparameters) 
                    {
                        foreach($structure->parts[$i]->parameters as $object) 
                        {
                            if(strtolower($object->attribute) == 'name') 
                            {
                                $attachments[$i]['is_attachment'] = true;
                                $attachments[$i]['name'] = $object->value;
                            }
                        }
                    }

                    if($attachments[$i]['is_attachment']) 
                    {
                        $attachments[$i]['attachment'] = imap_fetchbody($inbox, $email_number, $i+1);


                        /* 4 = QUOTED-PRINTABLE encoding */
                        if($structure->parts[$i]->encoding == 3) 
                        { 
                            $attachments[$i]['attachment'] = base64_decode($attachments[$i]['attachment']);
                        }
                        /* 3 = BASE64 encoding */
                        elseif($structure->parts[$i]->encoding == 4) 
                        { 
                            $attachments[$i]['attachment'] = quoted_printable_decode($attachments[$i]['attachment']);
                        }
                    }
                }
            }
        }

        /* iterate through each attachment and save it */
        foreach($attachments as $attachment)
        {

            if($attachment['is_attachment'] == 1)
            {

                    $filename = $attachment['name'];
                    if(empty($filename)) 
                    $filename = $attachment['filename'];

                if(!in_array($filename, $dowloadAttachments))
                {   
                    $dowloadAttachments[] =  $filename;

                    /* To check extension of attachment */
                    $info = pathinfo($filename);

                    $xlsExtension = array('xls','xlsm','xlss','csv');
                    if (in_array($info["extension"],$xlsExtension)) {




                        /* prefix the email number to the filename in case two emails
                         * have the attachment with the same file name.
                         */
                         $tmpFile = $filename;
                        $filename = $dateTime."/".$filename; 
                        $fp = fopen($filename, "w+");
                        fwrite($fp, $attachment['attachment']);
                        fclose($fp);
                        require "calculateValue.php";



}
                }
            }

答案 3 :(得分:0)

打开IMAP流,以从您的INBOX提取电子邮件并使用搜索条件搜索电子邮件。

$inbox = imap_open('{imap.gmail.com:993/imap/ssl}INBOX', $username, $password) or die('Cannot connect: ' . imap_last_error());

$inboxmails = imap_search($inbox, 'SUBJECT "'.$subject.'" SINCE "'.$since_date.'" BEFORE "'.$before_date.'"', SE_UID); 

您可以使用此代码提取多个附件,它可以正常工作并从单个邮件中提取多个附件。

您必须使用imap_open()打开流,然后才能使用imap_search()搜索消息。它返回您的电子邮件号码数组。

假设电子邮件号码为369。

    $email = 369;   
    $msgno = imap_msgno($inbox, $email);
    foreach($attachmentObj as $key => $val)
    {                   
        if($val['is_attachment']){
            echo "\nFilename: ".$val['filename']."\n";
            echo "Extension: ". pathinfo($val['filename'],PATHINFO_EXTENSION);
            //print_r($val);?>
            <img src="data:image/jpeg;base64,<?php echo base64_encode($val['attachment']);?>" width="200">
            <?php
        }
    }

要获取电子邮件附件,必须获取imap_fetchstructure,这将返回一个对象,您可以在其中检查是否有可用的附件。

function extract_attachments($connection, $message_number) {

    $attachments = array();
    $structure = imap_fetchstructure($connection, $message_number);

    if(isset($structure->parts) && count($structure->parts)) {

        for($i = 0; $i < count($structure->parts); $i++) {

            $attachments[$i] = array(
                'is_attachment' => false,
                'filename' => '',
                'name' => '',
                'attachment' => ''
            );

            if($structure->parts[$i]->ifdparameters) {
                foreach($structure->parts[$i]->dparameters as $object) {
                    if(strtolower($object->attribute) == 'filename') {
                        $attachments[$i]['is_attachment'] = true;
                        $attachments[$i]['filename'] = $object->value;
                    }
                }
            }

            if($structure->parts[$i]->ifparameters) {
                foreach($structure->parts[$i]->parameters as $object) {
                    if(strtolower($object->attribute) == 'name') {
                        $attachments[$i]['is_attachment'] = true;
                        $attachments[$i]['name'] = $object->value;
                    }
                }
            }

            if($attachments[$i]['is_attachment']) {
                $attachments[$i]['attachment'] = imap_fetchbody($connection, $message_number, $i+1);
                if($structure->parts[$i]->encoding == 3) { // 3 = BASE64
                    $attachments[$i]['attachment'] = base64_decode($attachments[$i]['attachment']);
                }
                elseif($structure->parts[$i]->encoding == 4) { // 4 = QUOTED-PRINTABLE
                    $attachments[$i]['attachment'] = quoted_printable_decode($attachments[$i]['attachment']);
                }
            }

        }

    }

    return $attachments;

}