Подтвердить что ты не робот

Imap - получить прикрепленный файл

Как получить прикрепленный файл из этого письма?

Это электронное письмо отправляется с яблочного компьютера, а стейт электронной почты не похож ни на один другой (сюрприз).. здесь часть с расположением - это одно измерение глубже, чем другое.

script работает с любым другим электронным адресом, где часть с файлом находится в первом измерении, но не с этим

$part->dparameters[0]->value возвращает имя файла, но strlen($data) возвращает 0

поток imap

$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
                                        )

                                )

                        )

                )

        )

)
4b9b3361

Ответ 1

Вы не указали правильный номер раздела для вложенных вложений. Вы должны передать номер раздела на рекурсивном шаге.

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";
            }
        }
    }
}

(Непроверенный, но должен поступать правильно...)

Ответ 2

Следующий код показывает каталоги и электронную почту в INBOX

    $mailbox = imap_open ("{correo.servidor.com:993/imap/ssl/novalidate-cert}INBOX", "[email protected]", "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);

Код test_imap_attachment.php, который показывает файлы вложений

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", "[email protected]", "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>";

Следующий код сохранит файл на том же сервере: 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", "[email protected]", "PASSWORD");


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

downloadAttachment($mailbox, $uid);

Я использовал код на этих страницах:

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

Загрузка вложений в каталог с IMAP в PHP, беспорядочно работает

Ответ 3

Я не знаю конкретно о письмах Mac, но вот какой-то код, который у меня есть, который проходит через каждую из частей, чтобы увидеть, является ли это "ATTACHMENT" и где-то сохраняет файл, поэтому я могу позвонить ему позже.

$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);
    }
}