PHP: Hypertext Preprocessor (original) (raw)

imap_fetchstructure

(PHP 4, PHP 5, PHP 7, PHP 8)

imap_fetchstructure — Read the structure of a particular message

Description

Parameters

imap

An IMAP\Connection instance.

message_num

The message number

flags

This optional parameter only has a single option, [FT_UID](imap.constants.php#constant.ft-uid), which tells the function to treat themessage_num argument as a UID.

Return Values

Returns an object with properties listed in the table below, or [false](reserved.constants.php#constant.false) on failure.

Returned Object for imap_fetchstructure()

type Primary body type
encoding Body transfer encoding
ifsubtype true if there is a subtype string
subtype MIME subtype
ifdescription true if there is a description string
description Content description string
ifid true if there is an identification string
id Identification string
lines Number of lines
bytes Number of bytes
ifdisposition true if there is a disposition string
disposition Disposition string
ifdparameters true if the dparameters array exists
dparameters An array of objects where each object has an"attribute" and a "value" property corresponding to the parameters on theContent-disposition MIME header.
ifparameters true if the parameters array exists
parameters An array of objects where each object has an"attribute" and a "value" property.
parts An array of objects identical in structure to the top-level object, each of which corresponds to a MIME body part.

Primary body type (value may vary with used library, use of constants is recommended)

Value Type Constant
0 text TYPETEXT
1 multipart TYPEMULTIPART
2 message TYPEMESSAGE
3 application TYPEAPPLICATION
4 audio TYPEAUDIO
5 image TYPEIMAGE
6 video TYPEVIDEO
7 model TYPEMODEL
8 other TYPEOTHER

Transfer encodings (value may vary with used library, use of constants is recommended)

Value Type Constant
0 7bit ENC7BIT
1 8bit ENC8BIT
2 Binary ENCBINARY
3 Base64 ENCBASE64
4 Quoted-Printable ENCQUOTEDPRINTABLE
5 other ENCOTHER

Changelog

Version Description
8.1.0 The imap parameter expects an IMAP\Connection instance now; previously, a valid imap resource was expected.

See Also

Found A Problem?

david at hundsness dot com

16 years ago

`Here is code to parse and decode all types of messages, including attachments. I've been using something like this for a while now, so it's pretty robust.

mbox=IMAPstream,mbox = IMAP stream, mbox=IMAPstream,mid = message id // output all the following: global charset,charset,charset,htmlmsg,$plainmsg,$attachments; htmlmsg=htmlmsg = htmlmsg=plainmsg = $charset = ''; attachments=array();//HEADER<spanclass="katex"><spanclass="katex−mathml"><mathxmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>h</mi><mo>=</mo><mi>i</mi><mi>m</mi><mi>a</mi><msub><mi>p</mi><mi>h</mi></msub><mi>e</mi><mi>a</mi><mi>d</mi><mi>e</mi><mi>r</mi><mostretchy="false">(</mo></mrow><annotationencoding="application/x−tex">h=imapheader(</annotation></semantics></math></span><spanclass="katex−html"aria−hidden="true"><spanclass="base"><spanclass="strut"style="height:0.6944em;"></span><spanclass="mordmathnormal">h</span><spanclass="mspace"style="margin−right:0.2778em;"></span><spanclass="mrel">=</span><spanclass="mspace"style="margin−right:0.2778em;"></span></span><spanclass="base"><spanclass="strut"style="height:1em;vertical−align:−0.25em;"></span><spanclass="mordmathnormal">ima</span><spanclass="mord"><spanclass="mordmathnormal">p</span><spanclass="msupsub"><spanclass="vlist−tvlist−t2"><spanclass="vlist−r"><spanclass="vlist"style="height:0.3361em;"><spanstyle="top:−2.55em;margin−left:0em;margin−right:0.05em;"><spanclass="pstrut"style="height:2.7em;"></span><spanclass="sizingreset−size6size3mtight"><spanclass="mordmathnormalmtight">h</span></span></span></span><spanclass="vlist−s">​</span></span><spanclass="vlist−r"><spanclass="vlist"style="height:0.15em;"><span></span></span></span></span></span></span><spanclass="mordmathnormal">e</span><spanclass="mordmathnormal">a</span><spanclass="mordmathnormal">d</span><spanclass="mordmathnormal"style="margin−right:0.02778em;">er</span><spanclass="mopen">(</span></span></span></span>mbox,attachments = array();// HEADER <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>h</mi><mo>=</mo><mi>i</mi><mi>m</mi><mi>a</mi><msub><mi>p</mi><mi>h</mi></msub><mi>e</mi><mi>a</mi><mi>d</mi><mi>e</mi><mi>r</mi><mo stretchy="false">(</mo></mrow><annotation encoding="application/x-tex">h = imap_header(</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal">h</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">ima</span><span class="mord"><span class="mord mathnormal">p</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">h</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord mathnormal">e</span><span class="mord mathnormal">a</span><span class="mord mathnormal">d</span><span class="mord mathnormal" style="margin-right:0.02778em;">er</span><span class="mopen">(</span></span></span></span>mbox,attachments=array();//HEADER<spanclass="katex"><spanclass="katexmathml"><mathxmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>h</mi><mo>=</mo><mi>i</mi><mi>m</mi><mi>a</mi><msub><mi>p</mi><mi>h</mi></msub><mi>e</mi><mi>a</mi><mi>d</mi><mi>e</mi><mi>r</mi><mostretchy="false">(</mo></mrow><annotationencoding="application/xtex">h=imapheader(</annotation></semantics></math></span><spanclass="katexhtml"ariahidden="true"><spanclass="base"><spanclass="strut"style="height:0.6944em;"></span><spanclass="mordmathnormal">h</span><spanclass="mspace"style="marginright:0.2778em;"></span><spanclass="mrel">=</span><spanclass="mspace"style="marginright:0.2778em;"></span></span><spanclass="base"><spanclass="strut"style="height:1em;verticalalign:0.25em;"></span><spanclass="mordmathnormal">ima</span><spanclass="mord"><spanclass="mordmathnormal">p</span><spanclass="msupsub"><spanclass="vlisttvlistt2"><spanclass="vlistr"><spanclass="vlist"style="height:0.3361em;"><spanstyle="top:2.55em;marginleft:0em;marginright:0.05em;"><spanclass="pstrut"style="height:2.7em;"></span><spanclass="sizingresetsize6size3mtight"><spanclass="mordmathnormalmtight">h</span></span></span></span><spanclass="vlists"></span></span><spanclass="vlistr"><spanclass="vlist"style="height:0.15em;"><span></span></span></span></span></span></span><spanclass="mordmathnormal">e</span><spanclass="mordmathnormal">a</span><spanclass="mordmathnormal">d</span><spanclass="mordmathnormal"style="marginright:0.02778em;">er</span><spanclass="mopen">(</span></span></span></span>mbox,mid); // add code here to get date, from, to, cc, subject... // BODY s=imapfetchstructure(s = imap_fetchstructure(s=imapfetchstructure(mbox,$mid); if (!$s->parts) // simple getpart($mbox,$mid,$s,0); // pass 0 as part-number else { // multipart: cycle through each part foreach ($s->parts as partno0=>partno0=>partno0=>p) getpart($mbox,$mid,$p,$partno0+1); } } function getpart($mbox,$mid,$p,$partno) { // $partno = '1', '2', '2.1', '2.1.3', etc for multipart, 0 if simple global htmlmsg,htmlmsg,htmlmsg,plainmsg,$charset,$attachments;// DECODE DATA data=(data = (data=(partno)? imap_fetchbody($mbox,$mid,$partno): // multipart imap_body($mbox,$mid); // simple // Any part may be encoded, even plain text messages, so check everything. if ($p->encoding==4) data=quotedprintabledecode(data = quoted_printable_decode(data=quotedprintabledecode(data); elseif ($p->encoding==3) data=base64decode(data = base64_decode(data=base64decode(data);// PARAMETERS // get all parameters, like charset, filenames of attachments, etc. $params = array(); if ($p->parameters) foreach ($p->parameters as x)<spanclass="katex"><spanclass="katex−mathml"><mathxmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>p</mi><mi>a</mi><mi>r</mi><mi>a</mi><mi>m</mi><mi>s</mi><mostretchy="false">[</mo><mi>s</mi><mi>t</mi><mi>r</mi><mi>t</mi><mi>o</mi><mi>l</mi><mi>o</mi><mi>w</mi><mi>e</mi><mi>r</mi><mostretchy="false">(</mo></mrow><annotationencoding="application/x−tex">params[strtolower(</annotation></semantics></math></span><spanclass="katex−html"aria−hidden="true"><spanclass="base"><spanclass="strut"style="height:1em;vertical−align:−0.25em;"></span><spanclass="mordmathnormal">p</span><spanclass="mordmathnormal">a</span><spanclass="mordmathnormal"style="margin−right:0.02778em;">r</span><spanclass="mordmathnormal">am</span><spanclass="mordmathnormal">s</span><spanclass="mopen">[</span><spanclass="mordmathnormal">s</span><spanclass="mordmathnormal">t</span><spanclass="mordmathnormal"style="margin−right:0.02778em;">r</span><spanclass="mordmathnormal">t</span><spanclass="mordmathnormal">o</span><spanclass="mordmathnormal"style="margin−right:0.01968em;">l</span><spanclass="mordmathnormal">o</span><spanclass="mordmathnormal"style="margin−right:0.02691em;">w</span><spanclass="mordmathnormal"style="margin−right:0.02778em;">er</span><spanclass="mopen">(</span></span></span></span>x−>attribute)]=x) <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>p</mi><mi>a</mi><mi>r</mi><mi>a</mi><mi>m</mi><mi>s</mi><mo stretchy="false">[</mo><mi>s</mi><mi>t</mi><mi>r</mi><mi>t</mi><mi>o</mi><mi>l</mi><mi>o</mi><mi>w</mi><mi>e</mi><mi>r</mi><mo stretchy="false">(</mo></mrow><annotation encoding="application/x-tex">params[strtolower(</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">p</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">am</span><span class="mord mathnormal">s</span><span class="mopen">[</span><span class="mord mathnormal">s</span><span class="mord mathnormal">t</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">t</span><span class="mord mathnormal">o</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">o</span><span class="mord mathnormal" style="margin-right:0.02691em;">w</span><span class="mord mathnormal" style="margin-right:0.02778em;">er</span><span class="mopen">(</span></span></span></span>x->attribute)] = x)<spanclass="katex"><spanclass="katexmathml"><mathxmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>p</mi><mi>a</mi><mi>r</mi><mi>a</mi><mi>m</mi><mi>s</mi><mostretchy="false">[</mo><mi>s</mi><mi>t</mi><mi>r</mi><mi>t</mi><mi>o</mi><mi>l</mi><mi>o</mi><mi>w</mi><mi>e</mi><mi>r</mi><mostretchy="false">(</mo></mrow><annotationencoding="application/xtex">params[strtolower(</annotation></semantics></math></span><spanclass="katexhtml"ariahidden="true"><spanclass="base"><spanclass="strut"style="height:1em;verticalalign:0.25em;"></span><spanclass="mordmathnormal">p</span><spanclass="mordmathnormal">a</span><spanclass="mordmathnormal"style="marginright:0.02778em;">r</span><spanclass="mordmathnormal">am</span><spanclass="mordmathnormal">s</span><spanclass="mopen">[</span><spanclass="mordmathnormal">s</span><spanclass="mordmathnormal">t</span><spanclass="mordmathnormal"style="marginright:0.02778em;">r</span><spanclass="mordmathnormal">t</span><spanclass="mordmathnormal">o</span><spanclass="mordmathnormal"style="marginright:0.01968em;">l</span><spanclass="mordmathnormal">o</span><spanclass="mordmathnormal"style="marginright:0.02691em;">w</span><spanclass="mordmathnormal"style="marginright:0.02778em;">er</span><spanclass="mopen">(</span></span></span></span>x>attribute)]=x->value; if ($p->dparameters) foreach ($p->dparameters as x)<spanclass="katex"><spanclass="katex−mathml"><mathxmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>p</mi><mi>a</mi><mi>r</mi><mi>a</mi><mi>m</mi><mi>s</mi><mostretchy="false">[</mo><mi>s</mi><mi>t</mi><mi>r</mi><mi>t</mi><mi>o</mi><mi>l</mi><mi>o</mi><mi>w</mi><mi>e</mi><mi>r</mi><mostretchy="false">(</mo></mrow><annotationencoding="application/x−tex">params[strtolower(</annotation></semantics></math></span><spanclass="katex−html"aria−hidden="true"><spanclass="base"><spanclass="strut"style="height:1em;vertical−align:−0.25em;"></span><spanclass="mordmathnormal">p</span><spanclass="mordmathnormal">a</span><spanclass="mordmathnormal"style="margin−right:0.02778em;">r</span><spanclass="mordmathnormal">am</span><spanclass="mordmathnormal">s</span><spanclass="mopen">[</span><spanclass="mordmathnormal">s</span><spanclass="mordmathnormal">t</span><spanclass="mordmathnormal"style="margin−right:0.02778em;">r</span><spanclass="mordmathnormal">t</span><spanclass="mordmathnormal">o</span><spanclass="mordmathnormal"style="margin−right:0.01968em;">l</span><spanclass="mordmathnormal">o</span><spanclass="mordmathnormal"style="margin−right:0.02691em;">w</span><spanclass="mordmathnormal"style="margin−right:0.02778em;">er</span><spanclass="mopen">(</span></span></span></span>x−>attribute)]=x) <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>p</mi><mi>a</mi><mi>r</mi><mi>a</mi><mi>m</mi><mi>s</mi><mo stretchy="false">[</mo><mi>s</mi><mi>t</mi><mi>r</mi><mi>t</mi><mi>o</mi><mi>l</mi><mi>o</mi><mi>w</mi><mi>e</mi><mi>r</mi><mo stretchy="false">(</mo></mrow><annotation encoding="application/x-tex">params[strtolower(</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">p</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">am</span><span class="mord mathnormal">s</span><span class="mopen">[</span><span class="mord mathnormal">s</span><span class="mord mathnormal">t</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">t</span><span class="mord mathnormal">o</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">o</span><span class="mord mathnormal" style="margin-right:0.02691em;">w</span><span class="mord mathnormal" style="margin-right:0.02778em;">er</span><span class="mopen">(</span></span></span></span>x->attribute)] = x)<spanclass="katex"><spanclass="katexmathml"><mathxmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>p</mi><mi>a</mi><mi>r</mi><mi>a</mi><mi>m</mi><mi>s</mi><mostretchy="false">[</mo><mi>s</mi><mi>t</mi><mi>r</mi><mi>t</mi><mi>o</mi><mi>l</mi><mi>o</mi><mi>w</mi><mi>e</mi><mi>r</mi><mostretchy="false">(</mo></mrow><annotationencoding="application/xtex">params[strtolower(</annotation></semantics></math></span><spanclass="katexhtml"ariahidden="true"><spanclass="base"><spanclass="strut"style="height:1em;verticalalign:0.25em;"></span><spanclass="mordmathnormal">p</span><spanclass="mordmathnormal">a</span><spanclass="mordmathnormal"style="marginright:0.02778em;">r</span><spanclass="mordmathnormal">am</span><spanclass="mordmathnormal">s</span><spanclass="mopen">[</span><spanclass="mordmathnormal">s</span><spanclass="mordmathnormal">t</span><spanclass="mordmathnormal"style="marginright:0.02778em;">r</span><spanclass="mordmathnormal">t</span><spanclass="mordmathnormal">o</span><spanclass="mordmathnormal"style="marginright:0.01968em;">l</span><spanclass="mordmathnormal">o</span><spanclass="mordmathnormal"style="marginright:0.02691em;">w</span><spanclass="mordmathnormal"style="marginright:0.02778em;">er</span><spanclass="mopen">(</span></span></span></span>x>attribute)]=x->value;// ATTACHMENT // Any part with a filename is an attachment, // so an attached text file (type 0) is not mistaken as the message. if ($params['filename'] || $params['name']) { // filename may be given as 'Filename' or 'Name' or both filename=(filename = (filename=(params['filename'])? params[′filename′]:params['filename'] : params[filename]:params['name']; // filename may be encoded, so see imap_mime_header_decode() attachments[attachments[attachments[filename] = $data; // this is a problem if two files have same name }// TEXT if ($p->type==0 && $data) { // Messages may be split in different parts because of inline attachments, // so append parts together with blank row. if (strtolower($p->subtype)=='plain') plainmsg.=trim(plainmsg. = trim(plainmsg.=trim(data) ."\n\n"; else htmlmsg.=htmlmsg. = htmlmsg.=data ."

"; charset=charset = charset=params['charset']; // assume all parts are same charset }// EMBEDDED MESSAGE // Many bounce notifications embed the original message as type 2, // but AOL uses type 1 (multipart), which is not handled here. // There are no PHP functions to parse embedded messages, // so this just appends the raw source to the main message. elseif ($p->type==2 && $data) { plainmsg.=plainmsg. = plainmsg.=data."\n\n"; }// SUBPART RECURSION if ($p->parts) { foreach ($p->parts as partno0=>partno0=>partno0=>p2) getpart($mbox,$mid,$p2,$partno.'.'.($partno0+1)); // 1.2, 1.2.1, etc. } } ?>

`

mkknapp at quadrapod dot com

24 years ago

`Assuming struct=imapfetchstructure(struct = imap_fetchstructure(struct=imapfetchstructure(x,$y);

It is important to note that if a message has NO attachements, struct−>partsisanemptyarray,andstruct->parts is an empty array, and struct>partsisanemptyarray,andstruct->bytes has a value. If a message as ANY attachements, $struct->bytes ALWAYS = 0. To get the size of the primary body, you have to call structure->part[0]->bytes. To get the size of the whole message, either strlen(imap_body) or add up the ->bytes of all the parts.

Another interesting note:
When there is body text and no attachements:
count($struct->parts) = 0
When there is body text and 1 attachement:
count($struct->parts) = 2

These imap functions could really use better documentation. Like giving the meathods for the dparameter and parameter classes...

`

chrislhill at "O_o" hotmail dot com

21 years ago

`For people just beging this may help alot as I spent a couple hours just trying to relize how exact the array was stored. (at the time I did not know the print_r function :P) struct=imapfetchstructure(struct = imap_fetchstructure(struct=imapfetchstructure(mbox, $msgnumber);
print_r($struct);

Will give you a better example for your messages but they are called as $struct using the varible method above.

$struct->type; //would return the type
$struct->encoding //would return the encoding

and etc..

This can be done many different ways but that is the basics on pulling the info out of the structure of fetchstructure itself, I hope it helps someone starting because it wouldve helped me :/.

`

sirber at detritus dot qc dot ca

19 years ago

"Primary body type" of "unknown/unknown" will be int(9).

masterbassist

20 years ago

`I think the following line (when building attachment information)

"filename" => parts[parts[parts[i]->parameters[0]->value

needs to be

"filename" => parts[parts[parts[i]->dparameters[0]->value

The first version generated a PHP warning under PHP 5.0.3. The second version actually gets the filename.

`

phpnet,a,emailaddress,cjb,net

17 years ago

`Another comment to inform people about something that should really be in the function description:

imap_fetchstructure() downloads the entire email, attachments and all, rather than just the structure.
I guess it's an undocumented feature, not a bug.

I had assumed that the script would have only downloaded the amount of data that was returned, but my script downloaded a cumulative 2.5gig before i noticed. Hopefully no-one else will have this happen.

`

hello at ivanbogomolov dot ru

6 years ago

`If you logic based on compare structure strings, you must compare it case insensetive.
<?php

$p

= imap_fetchstructure($this->_imap_resource, $mid);
//do not compare $p->disposition == 'INLINE'
if(preg_match('/inline/i', $p->disposition))
{
//this works
}
?>`

alchrystal88 at web dot de

6 years ago

`If you have errors with wrong attachment names like this:

correct name:
String -> Prüfbericht Hersteller.pdf

fetchstructure object name:
=?ISO-8859-1?Q?Pr=FCfbericht_Hersteller=2Epdf?=

Workaround to reconvert:

imap_mime_header_decode($fetchstructure->dparameters->value)[0]->text

imap_mime_header_decode($filename)[0]->text

`

es96 at hotmail dot com

21 years ago

`If you are getting CHARSET as US-ASCII even if the header has a Content-Type: field, make sure the header also has a MIME-Version: field.

For example, the following header will correcty report charset as KOI8-R

MIME-Version: 1.0
Content-Type: text/plain; charset="koi8-r"

Without the MIME-Version it will be reported as US-ASII

`

jcastro at elnuevodia dot com

22 years ago

I think the above note about attachments is wrong. I tested sending files with and without attachments and I get the following<br> with attachment: type=3 bytes=343648 no attachment: type=0 bytes=2 so checking for $struct->bytes == " " means nothing. At least in my test running windows 2000, php4.2.1 using outlook and exchange. It seems that cheking the type will be more reliable

hholzgra at media-engineering dot de

25 years ago

`the parts objects are identical in
structure to those returned by imap_fetchstructure, describing one subfolder each

parameters and dparameters are MIME-specific, theese contain the
extra parameters provided in the Content-Type and Content-Disposion Header lines such as Charset or Filename

`