I'm using the below function to get attachments from an email (index $m) on an existing imap connection ($imap)
function parse_parts(&$structure, &$attachments, &$imap, $m, $par){
if(isset($structure->parts) && count($structure->parts) ) {
for($i = 0; $i < count($structure->parts); $i++) {
$attachments[] = array(
'is_attachment' => false,
'filename' => '',
'name' => '',
'attachment' => ''
);
$lstk= array_keys($attachments); $j=end($lstk); // use this instead of $i to avoid overlapping indices when there's sub-parts and recursion
if($structure->parts[$i]->ifdparameters) {
foreach($structure->parts[$i]->dparameters as $object) {
if(strtolower($object->attribute) == 'filename') {
$attachments[$j]['is_attachment'] = true;
$attachments[$j]['filename'] = $object->value;
}
}
}
if($structure->parts[$i]->ifparameters) {
foreach($structure->parts[$i]->parameters as $object) {
if(strtolower($object->attribute) == 'name') {
$attachments[$j]['is_attachment'] = true;
$attachments[$j]['filename'] = imap_utf8($object->value);
}
}
}
if($attachments[$j]['is_attachment']) {
if($par==''){
$attachments[$j]['attachment'] = imap_fetchbody($imap, $m, $i+1);
}else{
$attachments[$j]['attachment'] = imap_fetchbody($imap, $m, $par . $i+1);
}
if($structure->parts[$i]->encoding == 3) { // 3 = BASE64
$attachments[$j]['attachment'] = base64_decode($attachments[$j]['attachment']);
}
elseif($structure->parts[$i]->encoding == 4) { // 4 = QUOTED-PRINTABLE
$attachments[$j]['attachment'] = quoted_printable_decode($attachments[$j]['attachment']);
}else{echo "encod:". $structure->parts[$i]->encoding . PHP_EOL; }
}
if(isset($structure->parts[$i]->parts) && count($structure->parts[$i]->parts)){ //if the part contains its own parts, recurse
$prnt = $i;
$prnt = $prnt . '.';
parse_parts($structure->parts[$i], $attachments, $imap, $m, $prnt );
}
}
}
}
the later function which calls this looks like:
$structure = imap_fetchstructure($imap, $m);
$attachments = array();
parse_parts($structure, $attachments, $imap, $m, '');
the standard function works fine, but when it has to recurse (i.e. there are nested parts), the resulting file is not readable, though it does appear to be the correct size. Any idea what i'm doing wrong? i've tried changing $prnt to
$prnt = $i+1 .'.';
but then, it just outputs an empty file. i noticed that other people had similar issues here: imap - get attached file
but their solutions don't appear to work for this email/code.