Posted By

d4rk on 05/14/07


Tagged

php mime pop3 imap


Versions (?)

Who likes this?

2 people have marked this snippet as a favorite

vali29
hudge


Parsing MIME email into parts


 / Published in: PHP
 

URL: http://us.php.net/manual/en/function.imap-fetchbody.php

  1. The function imap_fetchbody() seems uncapable of getting subordinate parts of a message/rfc822-part. I had problems with getting an attachment that was forwarded in such a part, because the object given by imap_fetchstructure() would assume that the part was represented by the string "2.1.2.1.2".
  2.  
  3. So I wrote this set of functions which parses the raw message-body and creates an array with the struture corresponding to the structure given by imap_fetchstructure(). The function mail_fetchpart() (see below) will work on the array and return even those parts that I could not get with imap_fetchbody().
  4.  
  5. Example usage of this function: mail_fetchpart($mbox, 2, "2.1.2.1.2");
  6.  
  7. Note: If the message does not contain multiple pars, the body of the message can be accessed by the part-string "1".
  8. I have more functions for parsing and decoding messages, just email me.
  9.  
  10. // get the body of a part of a message according to the
  11. // string in $part
  12. function mail_fetchpart($mbox, $msgNo, $part) {
  13. $parts = mail_fetchparts($mbox, $msgNo);
  14.  
  15. $partNos = explode(".", $part);
  16.  
  17. $currentPart = $parts;
  18. while(list ($key, $val) = each($partNos)) {
  19. $currentPart = $currentPart[$val];
  20. }
  21.  
  22. if ($currentPart != "") return $currentPart;
  23. else return false;
  24. }
  25.  
  26. // splits a message given in the body if it is
  27. // a mulitpart mime message and returns the parts,
  28. // if no parts are found, returns false
  29. function mail_mimesplit($header, $body) {
  30. $parts = array();
  31.  
  32. $PN_EREG_BOUNDARY = "Content-Type:(.*)boundary=\"([^\"]+)\"";
  33.  
  34. if (eregi ($PN_EREG_BOUNDARY, $header, $regs)) {
  35. $boundary = $regs[2];
  36.  
  37. $delimiterReg = "([^
  38. ]*)$boundary([^
  39. ]*)";
  40. if (eregi ($delimiterReg, $body, $results)) {
  41. $delimiter = $results[0];
  42. $parts = explode($delimiter, $body);
  43. $parts = array_slice ($parts, 1, -1);
  44. }
  45.  
  46. return $parts;
  47. } else {
  48. return false;
  49. }
  50.  
  51.  
  52. }
  53.  
  54. // returns an array with all parts that are
  55. // subparts of the given part
  56. // if no subparts are found, return the body of
  57. // the current part
  58. function mail_mimesub($part) {
  59. $i = 1;
  60. $headDelimiter = "
  61.  
  62. ";
  63. $delLength = strlen($headDelimiter);
  64.  
  65. // get head & body of the current part
  66. $endOfHead = strpos( $part, $headDelimiter);
  67. $head = substr($part, 0, $endOfHead);
  68. $body = substr($part, $endOfHead + $delLength, strlen($part));
  69.  
  70. // check whether it is a message according to rfc822
  71. if (stristr($head, "Content-Type: message/rfc822")) {
  72. $part = substr($part, $endOfHead + $delLength, strlen($part));
  73. $returnParts[1] = mail_mimesub($part);
  74. return $returnParts;
  75. // if no message, get subparts and call function recursively
  76. } elseif ($subParts = mail_mimesplit($head, $body)) {
  77. // got more subparts
  78. while (list ($key, $val) = each($subParts)) {
  79. $returnParts[$i] = mail_mimesub($val);
  80. $i++;
  81. }
  82. return $returnParts;
  83. } else {
  84. return $body;
  85. }
  86. }
  87.  
  88. // get an array with the bodies all parts of an email
  89. // the structure of the array corresponds to the
  90. // structure that is available with imap_fetchstructure
  91. function mail_fetchparts($mbox, $msgNo) {
  92. $parts = array();
  93. $header = imap_fetchheader($mbox,$msgNo);
  94. $body = imap_body($mbox,$msgNo, FT_INTERNAL);
  95.  
  96. $i = 1;
  97.  
  98. if ($newParts = mail_mimesplit($header, $body)) {
  99. while (list ($key, $val) = each($newParts)) {
  100. $parts[$i] = mail_mimesub($val);
  101. $i++;
  102. }
  103. } else {
  104. $parts[$i] = $body;
  105. }
  106. return $parts;
  107.  
  108. }

Report this snippet  

Comments

RSS Icon Subscribe to comments
Posted By: sterichards on July 30, 2007

Hello.

I was hoping you have some code that could parse rfc822 attachments. I have a setup where people using Microsoft Outlook can selected multiple e-mails from their inbox and use 'Forward Items' and then the selected e-mails are sent as attachments to an e-mail that is created. I have found that there aren't any functions that seem capable of parsing those attachments individually. All IMAP functions within PHP and classes that I have downloaded parse all of the message attachments as the body of the e-mail that is sent.

Regards, Stephen

You need to login to post a comment.