Item not being properly indexed in PHP array inside of for loop

55 views Asked by At

I have a for loop that is pulling attachments from email using PHP's IMAP functions. This works fine for one attachment, but it is unable to pull more than one attachment from a single mail. See code below -

for ($i = 0; $i < $count; $i++) {
  $attachments[$i] = array( 'is_attachment' => FALSE );
  if ($email['structure']->parts[$i]->ifdparameters) {
    foreach ($email['structure']->parts[$i]->dparameters as $object) {
      if (strtolower($object->attribute) == 'filename') {
        $attachments[$i]['is_attachment'] = TRUE;
        $attachments[$i]['filename'] = $object->value;
      }
    }
  }
  if ($email['structure']->parts[$i]->ifparameters) {
    foreach ($email['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($this->conn, $email['index'], $i+1);     
    $attachments[$i]['attachment'] = base64_decode($attachments[$i]['attachment']);                       
  }
  error_log(print_r($attachments[$i], TRUE));
  error_log(print_r($attachments, TRUE));
}

It appears that the second attachment is not being correctly added to the array's index. My error logging shows a value for $attachment[$i] at each value (0, 1, 2), however, $attachment only contains 2 indexes (0, 1). The first is a blank value (part of the email), and the second and third are attachments. See sample error log output below -

[13-Jun-2015 16:19:54 Europe/Berlin] Array ( [is_attachment] => )
[13-Jun-2015 16:19:54 Europe/Berlin] Array ( [0] => Array ([is_attachment] => ))
[13-Jun-2015 16:19:55 Europe/Berlin] Array (
  [is_attachment] => 1
  [filename] => 2015-06-12_1048.png
  [name] => 2015-06-12_1048.png
  [attachment] => ‰PNG
[13-Jun-2015 16:19:55 Europe/Berlin] Array ( 
  [0] => Array ( [is_attachment] => )
  [1] => Array  (
    [is_attachment] => 1
    [filename] => 2015-06-12_1048.png
    [name] => 2015-06-12_1048.png
    [attachment] => ‰PNG
[13-Jun-2015 16:19:55 Europe/Berlin] Array (
  [is_attachment] => 1
  [filename] => 5812548c-d445-4a18-a56d-e2698fdfd99b.jpg
  [name] => 5812548c-d445-4a18-a56d-e2698fdfd99b.jpg
  [attachment] => ÿØÿà
[13-Jun-2015 16:19:55 Europe/Berlin] Array ( 
  [0] => Array ( [is_attachment] => )
  [1] => Array (
    [is_attachment] => 1
    [filename] => 2015-06-12_1048.png
    [name] => 2015-06-12_1048.png
    [attachment] => ‰PNG

As you can see, the third item, $attachments[2] is an array [attachment] => ÿØÿà, however it is not added to array when I print $attachments. I'm really at a loss here why it shows when printing $attachments[$i] but not $attachments. Any ideas?

Update: error logging is broken due to binary files + likely null character. The problem still exists that I can't pull more than one attachment though. I am saving the binaries in $attachments array to disk, and only one attachment is saved, not both of them. Why would only the first binary get saved?

1

There are 1 answers

0
Siguza On BEST ANSWER

Alright, I'm posting this as an answer then, so this question can be marked as answered:

This appears to be a purely visual bug.
The error logs you provided seem to be incomplete, all output after any [attachment] => seems to be cut off (there should at least be closing brackets to close Array ( ..., right?).
This is most likely caused by

  1. those files containing a null character (\0), which is rather likely for binary files of a certain length.
  2. The error handler not using byte arrays, but C-style strings, whose end is indicated by said null character.

So when logging the data it appears to be broken, when in fact, it is just fine.