Search code examples
phpemailimap

php counts on how many attachments in a single email


I am working on my PHP to counting the value for how many attachments I have got in a single email.

When I try this:

echo count($structure->parts);

The output will show like this:

3

I have got 2 attachments in a single email so the output return is incorrect. So when I tried this:

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

The output return like this:

012

Here is the full code:

<?php

require_once "Mail.php";
require_once('Mail/IMAPv2.php');

$username = 'myusername';
$password = 'mypassword';
$mailserver = '{imap.domain.com:993/imap/ssl/novalidate-cert}INBOX';
$mailbox = imap_open($mailserver, $username, $password) or die("Can't connect: " . imap_last_error());
$key = "mykey";
$email_number = openssl_decrypt(hex2bin('274'),'AES-128-CBC', $key);
$attach_id = $_GET['attid'];

/* get information specific to this email */
$overview = imap_fetch_overview($mailbox, $email_number, 0);

$message = imap_fetchbody($mailbox, $email_number, 2);

/* get mail structure */
$structure = imap_fetchstructure($mailbox, $email_number);
$attachments = array();


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

I have got 2 attachments in a single email so the return output should show 2 not 3 or 012 which is still show 3. I have tried to find the answer on google how I could counting the value for attachments in a single email using imap, but I am unable to do so.

Can you please show me an example how I can counting on how many attachments I have got in a single email?

Thank you.

EDIT: Here is the output for the $structure->parts:

Array ( [0] => stdClass Object ( [type] => 1 [encoding] => 0 [ifsubtype] => 1 [subtype] => 
ALTERNATIVE [ifdescription] => 0 [ifid] => 0 [ifdisposition] => 0 [ifdparameters] => 0 
[ifparameters] => 1 [parameters] => Array ( [0] => stdClass Object ( [attribute] => boundary 
[value] => 00000000000014af61058c780612 ) ) [parts] => Array ( [0] => stdClass Object ( [type] => 0 
[encoding] => 0 [ifsubtype] => 1 [subtype] => PLAIN [ifdescription] => 0 [ifid] => 0 [lines] => 3 
[bytes] => 42 [ifdisposition] => 0 [ifdparameters] => 0 [ifparameters] => 1 [parameters] => 
Array ( [0] => stdClass Object ( [attribute] => charset [value] => UTF-8 ) ) ) [1] => 
stdClass Object ( [type] => 0 [encoding] => 4 [ifsubtype] => 1 [subtype] => HTML [ifdescription] => 0 
[ifid] => 0 [lines] => 4 
[bytes] => 307 [ifdisposition] => 0 [ifdparameters] => 0 [ifparameters] => 1 [parameters] => 
Array ( [0] => stdClass Object ( [attribute] => charset [value] => UTF-8 ) ) ) ) ) [1] => 
stdClass Object ( [type] => 3 [encoding] => 3 [ifsubtype] => 1 [subtype] => OCTET-STREAM 
[ifdescription] => 0 [ifid] => 1 [id] => [bytes] => 99376 [ifdisposition] => 1 [disposition] => 
attachment [ifdparameters] => 1 [dparameters] => Array ( [0] => stdClass Object ( [attribute] => 
filename [value] => 2019-01-23 (1).rar ) ) [ifparameters] => 1 [parameters] => Array ( [0] => 
stdClass Object ( [attribute] => name [value] => 2019-01-23 (1).rar ) ) ) [2] => stdClass Object 
( [type] => 3 [encoding] => 3 [ifsubtype] => 1 [subtype] => X-ZIP-COMPRESSED [ifdescription] => 0 
[ifid] => 1 [id] => [bytes] => 250846 [ifdisposition] => 1 [disposition] => attachment 
[ifdparameters] => 1 [dparameters] => Array ( [0] => stdClass Object ( [attribute] => filename 
[value] => email.zip ) ) [ifparameters] => 1 [parameters] => Array ( [0] => 
stdClass Object ( [attribute] => name [value] => email.zip ) ) ) )

Solution

  • Please take a closer look at the contents of $structure->parts. You have an array of 3 parts, the last two of which contain the following properties:

    [ifdisposition] => 1 
    [disposition] => attachment
    

    Since the first part contains [ifdisposition] => 0 and the [disposition] property does not exist, we can infer that ifdisposition is a boolean which tells you whether or not disposition is available. We can verify this by checking the PHP documentation for imap_fetchstructure().

    To find all attachments, you should iterate over the parts and match all cases where ifdisposition === true and disposition === 'attachment'. If you wanted to extract all of these quickly, you could do something like the following:

    $attachments = array_filter($structure->parts, function($part) {
        return $part->ifdisposition && $part->disposition === 'attachment';
    });