ConFoo 2025

imap_fetchstructure

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

imap_fetchstructureLiefert die Struktur einer Nachricht

Beschreibung

imap_fetchstructure(IMAP\Connection $imap, int $message_num, int $flags = 0): stdClass|false

Gibt alle Strukturinformationen für die angegebene Nachricht zurück.

Parameter-Liste

imap

Eine IMAP\Connection-Instanz.

message_num

Die Nummer der Nachricht

flags

Dieser optionale Parameter hat nur eine einzige Option, FT_UID, die angibt, dass message_num als UID behandelt werden soll.

Rückgabewerte

Gibt ein Objekt mit Eigenschaften zurück, die in der Tabelle weiter unten aufgelistet werden. Bei einem Fehler wird false zurückgegeben.

Zurückgegebenes Objekt für imap_fetchstructure()
type Primärer Typ des Textkörpers
encoding Übertragungskodierung des Textkörpers
ifsubtype true, falls ein Untertyp-Eintrag existiert
subtype MIME-Untertyp
ifdescription true, falls ein Beschreibungstext existiert
description Beschreibungstext
ifid true, falls ein Identifikationstext existiert
id Identifikationstext
lines Anzahl der Zeilen
bytes Größe in Bytes
ifdisposition true, falls ein Eintrag zur Verwendungsart (disposition) existiert
disposition Verwendungsart
ifdparameters true, falls ein dparameters-Array existiert
dparameters Ein Array von Objekten, wobei jedes Objekt eine "attribute"- und eine "value"-Eigenschaft hat, die den Parametern der MIME-Kopfzeile Content-disposition entsprechen.
ifparameters true, falls ein "parameters"-Array existiert
parameters Ein Array von Objekten mit je einer "attribute"- und einer "value"-Eigenschaft.
parts Wenn der Nachrichtenteil selbst weitere untergeordnete MIME-Nachrichtenteile enthält, wird hier ein Array mit Objekten für diese Teile angelegt. Die Elemente dieses Arrays sind selbst jeweils wieder Objekte mit der hier beschriebenen Struktur.

Gängige primäre Nachrichtentypen (der Wert kann sich je nach Bibliothek ändern; die Verwendung der Konstanten wird empfohlen)
WertTypKonstante
0textTYPETEXT
1multipartTYPEMULTIPART
2messageTYPEMESSAGE
3applicationTYPEAPPLICATION
4audioTYPEAUDIO
5imageTYPEIMAGE
6videoTYPEVIDEO
7modelTYPEMODEL
8otherTYPEOTHER

Gängige Übertragungskodierungen (der Wert kann sich je nach Bibliothek ändern; die Verwendung der Konstanten wird empfohlen)
WertTypKonstante
07bitENC7BIT
18bitENC8BIT
2BinaryENCBINARY
3Base64ENCBASE64
4Quoted-PrintableENCQUOTEDPRINTABLE
5otherENCOTHER

Changelog

Version Beschreibung
8.1.0 Der Parameter imap erwartet nun eine IMAP\Connection-Instanz; vorher wurde eine gültige imap-resource erwartet.

Siehe auch

  • imap_fetchbody() - Liefert einen bestimmten Abschnitt aus dem Textkörper einer Nachricht
  • imap_bodystruct() - Liefert die Struktur eines bestimmten Nachrichtenteils

add a note

User Contributed Notes 12 notes

up
50
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.

<?php
function getmsg($mbox,$mid) {
// input $mbox = IMAP stream, $mid = message id
// output all the following:
global $charset,$htmlmsg,$plainmsg,$attachments;
$htmlmsg = $plainmsg = $charset = '';
$attachments = array();

// HEADER
$h = imap_header($mbox,$mid);
// add code here to get date, from, to, cc, subject...

// BODY
$s = imap_fetchstructure($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=>$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,$plainmsg,$charset,$attachments;

// DECODE 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 = quoted_printable_decode($data);
elseif (
$p->encoding==3)
$data = base64_decode($data);

// PARAMETERS
// get all parameters, like charset, filenames of attachments, etc.
$params = array();
if (
$p->parameters)
foreach (
$p->parameters as $x)
$params[strtolower($x->attribute)] = $x->value;
if (
$p->dparameters)
foreach (
$p->dparameters as $x)
$params[strtolower($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 = ($params['filename'])? $params['filename'] : $params['name'];
// filename may be encoded, so see imap_mime_header_decode()
$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($data) ."\n\n";
else
$htmlmsg. = $data ."<br><br>";
$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. = $data."\n\n";
}

// SUBPART RECURSION
if ($p->parts) {
foreach (
$p->parts as $partno0=>$p2)
getpart($mbox,$mid,$p2,$partno.'.'.($partno0+1)); // 1.2, 1.2.1, etc.
}
}
?>
up
3
mkknapp at quadrapod dot com
23 years ago
Assuming $struct = imap_fetchstructure($x,$y);

It is important to note that if a message has NO attachements, $struct->parts is an empty array, and $struct->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...
up
2
php AT firstnetimpressions.com
22 years ago
Point of clarification:

The seventh primary body type is not "Other" as documented, but actually "Model". This encompasses IGES, VRML, MESH, DWF, etc.

http://www.isi.edu/in-notes/iana/assignments/media-types/media-types

"Other" is the eigth primary body type.
up
2
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 = imap_fetchstructure($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 :/.
up
2
sirber at detritus dot qc dot ca
18 years ago
"Primary body type" of "unknown/unknown" will be int(9).
up
1
masterbassist
19 years ago
I think the following line (when building attachment information)

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

needs to be

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

The first version generated a PHP warning under PHP 5.0.3. The second version actually gets the filename.
up
2
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.
up
1
hello at ivanbogomolov dot ru
5 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
}
?>
up
1
alchrystal88 at web dot de
5 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
up
2
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
up
2
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
up
2
hholzgra at media-engineering dot de
24 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
To Top