To fetch the particular section of the body of a message with imap_fetchbody()
, you have to pass the section
parameter which relates to the IMAP part number and is defined as follow in the PHP documentation:
It is a string of integers delimited by period which index into a body part list as per the IMAP4 specification
The only clue I have is to use imap_fetchstructure()
to read the structure of a particular message. However, I don't know how to deduce the part numbers from it.
EDIT
For those interested in the IMAPv4 specification, here is the paragraph about fetching where part numbers are mentioned. Unfortunately, it does not clearly state how to get or compute them.
You are right, you have to use the result of the imap_fetchstructure()
function.
You can get the full listing of parts and subpart of a mail by using the following function :
function getPartList($struct, $base="") {
$res=Array();
if (!property_exists($struct,"parts")) {
return [$base?:"0"];
} else {
$num=1;
if (count($struct->parts)==1) return getPartList($struct->parts[0], $base);
foreach ($struct->parts as $p=>$part) {
foreach (getPartList($part, $p+1) as $subpart) {
$res[]=($base?"$base.":"").$subpart;
}
}
}
return $res;
}
$struct=imap_fetchstructure($mbox, $i);
$res=getPartList($struct);
print_r($res);
Result:
Array(
[0] => 1
[1] => 2
[2] => 3.1
[3] => 3.2
[4] => 4.1
[5] => 4.2
);
EDIT: be aware that your server may not handle RFC822 subpart
For instance on a Dovecot v2.2 server, it returns an empty string
telnet imapserver.com 143
a1 LOGIN [email protected] password
a2 SELECT "Inbox"
a3 FETCH 522 (BODY[3.1.2])
// result:
* 522 FETCH (BODY[3.1.2] {0}
)
a3 OK Fetch completed.
a4 logout
EDIT2 : it seems that subparts with only one part does not count... See modified code
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With