【问题标题】:Fetching email using PHP imap messes up inline embedded images使用 PHP imap 获取电子邮件会弄乱内联嵌入图像
【发布时间】:2017-05-20 04:48:47
【问题描述】:

我创建了一个 webmail php 类来获取我域的网络邮件。 一切运行完美,除了当电子邮件嵌入图像(如签名)时,图像在其 src 中使用 CID 获取,并且也被视为附件。

<img src="cid:auto_cid_2093934881" />

所以我最终得到了一个损坏的源图像(在电子邮件正文中的原始位置)和一个实际有效的相同图像的附件。但我不需要图像作为附件,我只是希望图像显示在它们的位置。

谁能帮我修复这个类,以便它可以正确获取图像?

这是我获取一封电子邮件的代码:

<?php
    $uid=mysql_real_escape_string($_GET['email_id']);
    ini_set("max_execution_time",360);

    /* connect to server */
    $hostname = '{***.com:143/notls}INBOX';
    $username = 'fadi@***.com';
    $password = '*******';

    /* try to connect */
    $inbox = imap_open($hostname,$username,$password) or die('Cannot connect to domain:' . imap_last_error());

    $overview = imap_fetch_overview($inbox,$uid,0);
    $header = imap_headerinfo($inbox, $uid);
    $fromaddr = $header->from[0]->mailbox . "@" . $header->from[0]->host;

    $webmail = new Webmail();
    $message = $webmail->getEmailBody($uid,$inbox);

    $attachments = $webmail->extract_attachments($inbox,$uid);
    $attach_hrefs = '';
    if(count($attachments)!=0){

        $target_dir = "emails/".$uid;
        if (!is_dir($target_dir)) {
          // dir doesn't exist, make it
          mkdir($target_dir);
        }

        foreach($attachments as $at){

            if($at[is_attachment]==1){

                file_put_contents($target_dir.'/'.$at[filename], $at[attachment]);
                $attach_hrefs .='<a target="new" href="'.$target_dir.'/'.$at[filename].'">'.$at[filename].'</a> ';

            }
        }

    }
?>

这是网络邮件类:

<?php
class Webmail{

function getEmailBody($uid, $imap)
{
    $body = $this->get_part($imap, $uid, "TEXT/HTML");
    // if HTML body is empty, try getting text body
    if ($body == "") {
        $body = $this->get_part($imap, $uid, "TEXT/PLAIN");
    }
    return $body;
}

function get_part($imap, $uid, $mimetype, $structure = false, $partNumber = false)
{
    if (!$structure) {
        $structure = imap_fetchstructure($imap, $uid, FT_UID);
    }
    if ($structure) {
        if ($mimetype == $this->get_mime_type($structure)) {
            if (!$partNumber) {
                $partNumber = 1;
            }
            $text = imap_fetchbody($imap, $uid, $partNumber, FT_UID);
            switch ($structure->encoding) {
                case 3:
                    return imap_base64($text);
                case 4:
                    return imap_qprint($text);
                default:
                    return $text;
            }
        }

        // multipart
        if ($structure->type == 1) {
            foreach ($structure->parts as $index => $subStruct) {
                $prefix = "";
                if ($partNumber) {
                    $prefix = $partNumber . ".";
                }
                $data = $this->get_part($imap, $uid, $mimetype, $subStruct, $prefix . ($index + 1));
                if ($data) {
                    return $data;
                }
            }
        }
    }
    return false;
}

function get_mime_type($structure)
{
    $primaryMimetype = ["TEXT", "MULTIPART", "MESSAGE", "APPLICATION", "AUDIO", "IMAGE", "VIDEO", "OTHER"];

    if ($structure->subtype) {
        return $primaryMimetype[(int)$structure->type] . "/" . $structure->subtype;
    }
    return "TEXT/PLAIN";
}
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;

  }
}
?>

提前致谢。

【问题讨论】:

    标签: php email imap webmail


    【解决方案1】:

    尝试使用下面的类来获取带有内联图像的邮件正文
    注意请参阅类中的 get_mail_body($body_type = 'html') 方法来存储邮件正文将图像内联到本地服务器,您需要将其更改为目录布局。

    希望对你有所帮助。

        $email_message = new Email_message();
        $mailbody = $email_message->get_mail_body();
    

    ;

    class Email_message {
    
        public $connection;
        public $messageNumber;    
        public $bodyHTML = '';
        public $bodyPlain = '';
        public $attachments;
        public $getAttachments = true;
    
        public function __construct($config_data = array()) {
    
            $this->connection = $config_data['connection'];
            $this->messageNumber = isset($config_data['message_no'])?$config_data['message_no']:1;
        }
    
        public function fetch() {
    
            $structure = @imap_fetchstructure($this->connection, $this->messageNumber);
            if(!$structure) {
                return false;
            }
            else {
                if(isset($structure->parts)){
                    $this->recurse($structure->parts);
                }
                return true;
            }
    
        }
    
        public function recurse($messageParts, $prefix = '', $index = 1, $fullPrefix = true) {
    
            foreach($messageParts as $part) {
    
                $partNumber = $prefix . $index;
    
                if($part->type == 0) {
                    if($part->subtype == 'PLAIN') {
                        $this->bodyPlain .= $this->getPart($partNumber, $part->encoding);
                    }
                    else {
                        $this->bodyHTML .= $this->getPart($partNumber, $part->encoding);
                    }
                }
                elseif($part->type == 2) {
                    $msg = new Email_message(array('connection' =>$this->connection,'message_no'=>$this->messageNumber));
                    $msg->getAttachments = $this->getAttachments;
                    if(isset($part->parts)){
                        $msg->recurse($part->parts, $partNumber.'.', 0, false);
                    }
                    $this->attachments[] = array(
                        'type' => $part->type,
                        'subtype' => $part->subtype,
                        'filename' => '',
                        'data' => $msg,
                        'inline' => false,
                    );
                }
                elseif(isset($part->parts)) {
                    if($fullPrefix) {
                        $this->recurse($part->parts, $prefix.$index.'.');
                    } else {
                        $this->recurse($part->parts, $prefix);
                    }
                }
                elseif($part->type > 2) {
                    if(isset($part->id)) {
                        $id = str_replace(array('<', '>'), '', $part->id);
                        $this->attachments[$id] = array(
                            'type' => $part->type,
                            'subtype' => $part->subtype,
                            'filename' => $this->getFilenameFromPart($part),
                            'data' => $this->getAttachments ? $this->getPart($partNumber, $part->encoding) : '',
                            'inline' => true,
                        );
                    } else {
                        $this->attachments[] = array(
                            'type' => $part->type,
                            'subtype' => $part->subtype,
                            'filename' => $this->getFilenameFromPart($part),
                            'data' => $this->getAttachments ? $this->getPart($partNumber, $part->encoding) : '',
                            'inline' => false,
                        );
                    }
                }
    
                $index++;
    
            }
    
        }
    
        function getPart($partNumber, $encoding) {
    
            $data = imap_fetchbody($this->connection, $this->messageNumber, $partNumber);
            switch($encoding) {
                case 0: return $data; // 7BIT
                case 1: return $data; // 8BIT
                case 2: return $data; // BINARY
                case 3: return base64_decode($data); // BASE64
                case 4: return quoted_printable_decode($data); // QUOTED_PRINTABLE
                case 5: return $data; // OTHER
            }
    
    
        }
    
        function getFilenameFromPart($part) {
    
            $filename = '';
    
            if($part->ifdparameters) {
                foreach($part->dparameters as $object) {
                    if(strtolower($object->attribute) == 'filename') {
                        $filename = $object->value;
                    }
                }
            }
    
            if(!$filename && $part->ifparameters) {
                foreach($part->parameters as $object) {
                    if(strtolower($object->attribute) == 'name') {
                        $filename = $object->value;
                    }
                }
            }
    
            return $filename;
    
        }
    
        function get_mail_body($body_type = 'html')
        {
            $mail_body = '';
            if($body_type == 'html'){
                $this->fetch();
                preg_match_all('/src="cid:(.*)"/Uims', $this->bodyHTML, $matches);
                if(count($matches)) {
                    $search = array();
                    $replace = array();
                    foreach($matches[1] as $match) {
                        $unique_filename = time().".".strtolower($this->attachments[$match]['subtype']);
                        file_put_contents("./uploads/$unique_filename", $this->attachments[$match]['data']);
                        $search[] = "src=\"cid:$match\"";
                        $replace[] = "src='".base_url()."/uploads/$unique_filename'";
                    }
                    $this->bodyHTML = str_replace($search, $replace, $this->bodyHTML);
                    $mail_body = $this->bodyHTML;
                }
            }else{
                    $mail_body = $this->bodyPlain;
            }
            return $mail_body;
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-06-13
      • 1970-01-01
      • 2019-12-14
      • 2013-02-08
      • 2011-03-27
      • 1970-01-01
      • 2011-07-26
      相关资源
      最近更新 更多