imap - get attached file

守給你的承諾、 提交于 2019-12-06 18:50:15

问题


How do I get the attached file from this email?

This email is sent from an apple computer and the email struture is not like any other (surprise).. here the part with the disposition is one dimension deeper than else..

The script works with every other email where the part with the file is in the first dimension, but not with this one

$part->dparameters[0]->value returns the file name, but strlen($data) returns 0

imap stream

$structure = imap_fetchstructure($this->stream, $this->msgno);

if(isset($structure->parts)){
    print_r($structure->parts);
    $this->parse_parts($structure->parts);
}

function parse_parts($parts){
    foreach($parts as $section => $part){
        if(isset($part->parts)){

            // some mails have one extra dimension
            $this->parse_parts($part->parts);

        }
        elseif(isset($part->disposition)){
            if(in_array(strtolower($part->disposition), array('attachment','inline'))){
                $data = imap_fetchbody($this->stream, $this->msgno, $section+1);
                echo $part->dparameters[0]->value.' '.strlen($data)."\n";
            }
        }
    }
}

print_r

Array
(
    [0] => stdClass Object
        (
            [type] => 0
            [encoding] => 0
            [ifsubtype] => 1
            [subtype] => PLAIN
            [ifdescription] => 0
            [ifid] => 0
            [lines] => 15
            [bytes] => 173
            [ifdisposition] => 0
            [ifdparameters] => 0
            [ifparameters] => 1
            [parameters] => Array
                (
                    [0] => stdClass Object
                        (
                            [attribute] => CHARSET
                            [value] => us-ascii
                        )

                )

        )

    [1] => stdClass Object
        (
            [type] => 1
            [encoding] => 0
            [ifsubtype] => 1
            [subtype] => MIXED
            [ifdescription] => 0
            [ifid] => 0
            [bytes] => 23420
            [ifdisposition] => 0
            [ifdparameters] => 0
            [ifparameters] => 1
            [parameters] => Array
                (
                    [0] => stdClass Object
                        (
                            [attribute] => BOUNDARY
                            [value] => Apple-Mail=_800896E0-A9C9-456E-B063-79CED9DD4FD7
                        )

                )

            [parts] => Array
                (
                    [0] => stdClass Object
                        (
                            [type] => 0
                            [encoding] => 0
                            [ifsubtype] => 1
                            [subtype] => HTML
                            [ifdescription] => 0
                            [ifid] => 0
                            [bytes] => 136
                            [ifdisposition] => 0
                            [ifdparameters] => 0
                            [ifparameters] => 1
                            [parameters] => Array
                                (
                                    [0] => stdClass Object
                                        (
                                            [attribute] => CHARSET
                                            [value] => us-ascii
                                        )

                                )

                        )

                    [1] => stdClass Object
                        (
                            [type] => 3
                            [encoding] => 3
                            [ifsubtype] => 1
                            [subtype] => PDF
                            [ifdescription] => 0
                            [ifid] => 0
                            [bytes] => 17780
                            [ifdisposition] => 1
                            [disposition] => INLINE
                            [ifdparameters] => 1
                            [dparameters] => Array
                                (
                                    [0] => stdClass Object
                                        (
                                            [attribute] => FILENAME
                                            [value] => 057 - LPJ - Stik og labels.pdf
                                        )

                                )

                            [ifparameters] => 1
                            [parameters] => Array
                                (
                                    [0] => stdClass Object
                                        (
                                            [attribute] => NAME
                                            [value] => 057 - LPJ - Stik og labels.pdf
                                        )

                                )

                        )

                    [2] => stdClass Object
                        (
                            [type] => 0
                            [encoding] => 4
                            [ifsubtype] => 1
                            [subtype] => HTML
                            [ifdescription] => 0
                            [ifid] => 0
                            [lines] => 75
                            [bytes] => 4931
                            [ifdisposition] => 0
                            [ifdparameters] => 0
                            [ifparameters] => 1
                            [parameters] => Array
                                (
                                    [0] => stdClass Object
                                        (
                                            [attribute] => CHARSET
                                            [value] => us-ascii
                                        )

                                )

                        )

                )

        )

)

回答1:


You are not providing the correct section number for nested attachments. You need to pass in the section number in the recursive step.

function parse_parts($parts, $parentsection = ""){
    foreach($parts as $subsection => $part){
        $section = $parentsection . ($subsection + 1);
        if(isset($part->parts)){

            // some mails have one extra dimension
            $this->parse_parts($part->parts, $section . "." );

        }
        elseif(isset($part->disposition)){
            if(in_array(strtolower($part->disposition), array('attachment','inline'))){
                $data = imap_fetchbody($this->stream, $this->msgno, $section );
                echo 'Getting section ' . $section;
                echo $part->dparameters[0]->value.' '.strlen($data)."\n";
            }
        }
    }
}

(Untested, but should do the right thing...)




回答2:


The next code shows you the directories and the email in the INBOX

    $mailbox = imap_open ("{correo.servidor.com:993/imap/ssl/novalidate-cert}INBOX", "correo@usuario.com", "PASSWORD");

    if (!$mailbox){
        die('murio');
    }

    echo "<h1>Buzones</h1>\n";
    $carpetas = imap_listmailbox($mailbox, "{correo.patronato.unam.mx:993}", "*");

    if ($carpetas == false) {
        echo "Llamada fallida<br />\n";
    } else {
        foreach ($carpetas as $val) {
            echo $val . "<br />\n";
        }
    }

    echo "<h1>Cabeceras en INBOX</h1>\n";
    $cabeceras = imap_headers($mailbox);

    if ($cabeceras == false) {
        echo "Llamada fallida<br />\n";
    } else {
        foreach ($cabeceras as $val) {
            echo $val . "<br />\n";
        }
    }



    $numMessages = imap_num_msg($mailbox);
    for ($i = $numMessages; $i > 0; $i--) {
        $header = imap_header($mailbox, $i);

        $fromInfo = $header->from[0];
        $replyInfo = $header->reply_to[0];

        // print_r($header);

        $details = array(
            "fromAddr" => (isset($fromInfo->mailbox) && isset($fromInfo->host))
                ? $fromInfo->mailbox . "@" . $fromInfo->host : "",
            "fromName" => (isset($fromInfo->personal))
                ? $fromInfo->personal : "",
            "replyAddr" => (isset($replyInfo->mailbox) && isset($replyInfo->host))
                ? $replyInfo->mailbox . "@" . $replyInfo->host : "",
            "replyName" => (isset($replyTo->personal))
                ? $replyto->personal : "",
            "subject" => (isset($header->subject))
                ? $header->subject : "",
            "udate" => (isset($header->udate))
                ? $header->udate : "",
            "Unseen" => (isset($header->Unseen))
                ? $header->Unseen  : "-"
        );
        $uid = imap_uid($mailbox, $i);

        echo "<ul>";
        echo "<li><strong>From:</strong>" . $details["fromName"];
        echo " " . $details["fromAddr"] . "</li>";
        echo "<li><strong>Subject:</strong> " . $details["subject"] . "</li>";
        echo "<li><strong>Estatus:</strong> " . $details["Unseen"] . "</li>";
        echo '<li><a href="test_imap_attachment.php?folder=' . $folder . '&uid=' . $i . '">Read</a></li>';
        echo "</ul>";
    }


    imap_close($mailbox);

The test_imap_attachment.php code that shows you the Attachments Files

function getAttachments($imap, $mailNum, $part, $partNum) {
    $attachments = array();

    if (isset($part->parts)) {
        foreach ($part->parts as $key => $subpart) {
            if($partNum != "") {
                $newPartNum = $partNum . "." . ($key + 1);
            }
            else {
                $newPartNum = ($key+1);
            }
            $result = getAttachments($imap, $mailNum, $subpart,
                $newPartNum);
            if (count($result) != 0) {
                 array_push($attachments, $result);
             }
        }
    }
    else if (isset($part->disposition)) {
        // print_r($part);
        if (strtoupper($part->disposition) == "ATTACHMENT") {
            $partStruct = imap_bodystruct($imap, $mailNum, $partNum);
            $attachmentDetails = array(
                "name"    => $part->dparameters[0]->value,
                "subtype" => $partStruct->subtype,
                "partNum" => $partNum,
                "enc"     => $partStruct->encoding
            );
            return $attachmentDetails;
        }
    }

    return $attachments;
}

$mailbox = imap_open ("{correo.servidor.com:993/imap/ssl/novalidate-cert}INBOX", "correo@usuario.com", "PASSWORD");

$uid = $_GET['uid'];

$mailStruct = imap_fetchstructure($mailbox, $uid);

$attachments = getAttachments($mailbox, $uid, $mailStruct, "");

echo "Attachments: ";
echo "<ul>";
foreach ($attachments as $attachment) {  
    echo '<li><a href="test_imap_download.php?func=' . $func . '&folder=' . $folder . '&uid=' . $uid .
        '&part=' . $attachment["partNum"] . '&enc=' . $attachment["enc"] . '">' .
        $attachment["name"] . "</a></li>";
}
echo "</ul>";

The next code save the file on the same server: test_imap_download.php

function downloadAttachment($imap, $uid) {
    $structure = imap_fetchstructure($imap, $uid);
    $attachments = '';
    if(isset($structure->parts) && count($structure->parts)) {
        for($i=0; $i<count($structure->parts); $i++) {
            if(strtoupper($structure->parts[$i]->disposition) == 'ATTACHMENT') {

                $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($imap, $uid, $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']);
                    }
                }

                file_put_contents('directorio/'.$attachments[$i]['filename'], $attachments[$i]['attachment']);

            }
        } 
    }
}   

$mailbox = imap_open ("{correo.servidor.com:993/imap/ssl/novalidate-cert}INBOX", "correo@usuario.com", "PASSWORD");


$uid        = $_GET["uid"];
$partNum    = $_GET["partNum"];

downloadAttachment($mailbox, $uid);

I have used code from this pages:

http://www.sitepoint.com/exploring-phps-imap-library-2/

Downloading attachments to directory with IMAP in PHP, randomly works




回答3:


I don't know specifically about Mac emails, but here is some code I have that goes through each of the parts to see if it's an "ATTACHMENT" and saves the file somewhere so I can call it later.

$body = imap_fetchstructure($box, $i);
$attachments = '';
$att = count($body->parts);
if($att >=2) {
for($a=0;$a<$att;$a++) {
if($body->parts[$a]->disposition == 'ATTACHMENT') {
$file = imap_base64(imap_fetchbody($box, $i, $a+1));
$string = genRandomString();
    if(!file_exists('/var/www/email_store/'.$_SESSION['site_user_id'])) {
        mkdir('/var/www/email_store/'.$_SESSION['site_user_id'].'/');   
    }
    $attachments .= $body->parts[$a]->dparameters[0]->value.'[#]'.$string.',';
    file_put_contents('/var/www/email_store/'.$_SESSION['site_user_id'].'/'.$string,$file);
    }
}       


来源:https://stackoverflow.com/questions/11285430/imap-get-attached-file

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!