views:

39

answers:

2

Hi!

PHP provides very useful functions to fetch emails from a POP3 account, in my case to handle bounce-mails. The function imap_fetchstructure(), however, gives me headache. When using it in one script, I (for some mails) get the message:

Notice: Unknown: Warning: MIME header encountered in non-MIME message (errflg=3) in Unknown on line 0

A Bug reported to PHP was set to status Bugus (http://bugs.php.net/bug.php?id=43471), but I fail to find a clue on this problem in the documentation.

Neither placing a @ before the function nor changing the error handler before the function (and resetting it after that) helps. Turning error reporting off or permanently changing the error handler or the error reporting level help (it seems that the error is triggered at the and of the script) - however, I need to register other errors that may occur after using this function.

Therefore I search for a hint at Stackoverflow: What exactly does the function mourn about (I guess a malformned MIME header or content) and how do I get rid of this error notice?

Thank you

+1  A: 

I believe the error message is emitted when you call imap_close(), or, in that function's absence, when the script ends. Try calling imap_errors() before that (to clear the error stack).

$struct = imap_fetchstructure($imap, $num);
$errs = imap_errors();
imap_close($imap);
GZipp
This is a prefectly working solution! I was not aware of the imap_errors() but it solves a lot of problems. Thank you! (Rating this answer will have to wait until I recevied enough reputation...)
BurninLeo
+2  A: 

The error is not emitted by php, that's probably why @ doesn't work. see below!

in the php source you'll find the function imap_fetchstructure() in ext/imap/php_imap.c, which is a wrapper for mail_fetchstructure_full(), which is a part of the c-client library.

In that library, in c-client/rfc822.c there's an interesting passage:

  case 'C':                 /* possible cc: or Content-<mumble>*/
    if (!strcmp (tmp+1,"C")) rfc822_parse_adrlist (&env->cc,d,host);
    else if ((tmp[1] == 'O') && (tmp[2] == 'N') && (tmp[3] == 'T') &&
             (tmp[4] == 'E') && (tmp[5] == 'N') && (tmp[6] == 'T') &&
             (tmp[7] == '-') && body)
      switch (MIMEp) {
      case -1:              /* unknown if MIME or not */
        if (!(MIMEp =       /* see if MIME-Version header exists */
              search ((unsigned char *) s-1,i,
                      (unsigned char *)"\012MIME-Version",(long) 13))) {
#if 1
         /* This is a disgusting kludge, and most of the messages which
           * benefit from it are spam.
           */
          if (!strcmp (tmp+8,"TRANSFER-ENCODING") ||
              (!strcmp (tmp+8,"TYPE") && strchr (d,'/'))) {
            MM_LOG ("Warning: MIME header encountered in non-MIME message",
                    PARSE);
            MIMEp = 1;      /* declare MIME now */
          }
          else
#endif

This is the only place generating your error, according to grep. So that explains most mysteries I think.

So you have a message with a CONTENT-TRANSFER-ENCODING or CONTENT-TYPE line, without a MIME-Version header.

edit MM_LOG is defined to mm_log, which is in turn a function that php/ext/imap/php_imap.c provides. The errors from imap_fetchstructure() are put in a list of errors (they are not output directly!) which you may query and empty using imap_errors(). Then, on shutdown of the resource, the errors are not displayed since the error list is empty.

mvds
Thank you! I had not considered about checking the PHP source for this error, but this explains a lot the manual does not disclose.
BurninLeo