Start · Sprachen · PHP · Referenz · imap_fetchstructure

imap_fetchstructure

Funktion

Liest die vollständige MIME-Struktur einer E-Mail-Nachricht und gibt sie als verschachtelte <code>stdClass</code>-Objekthierarchie zurück.

seit PHP 4.0.0 Kategorie: http

Signatur

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

Beschreibung

imap_fetchstructure() ruft die Struktur einer bestimmten Nachricht aus einem IMAP-Postfach ab. Das zurückgegebene Objekt beschreibt den MIME-Aufbau der Nachricht vollständig: Inhaltstyp, Zeichensatz, Kodierung, Dateianhänge und verschachtelte Multipart-Teile. Dies ist der primäre Einstiegspunkt, um eine E-Mail korrekt zu parsen und alle Bestandteile (Text, HTML, Anhänge) zuverlässig zu identifizieren.

Das Ergebnis-Objekt enthält u. a. die Felder type (primärer MIME-Typ, als Integer-Konstante), encoding (Übertragungskodierung), subtype (z. B. PLAIN, HTML), parameters (z. B. Zeichensatz), disposition (z. B. attachment) sowie bei Multipart-Nachrichten ein Array parts, das seinerseits wieder gleich aufgebaute Objekte enthält.

Mit dem optionalen Flag FT_UID kann statt der fortlaufenden Nachrichten-Sequenznummer eine UID verwendet werden, was bei IMAP-Sitzungen mit wechselnden Postfach-Zuständen stabiler ist. Die eigentlichen Inhalte einzelner Teile werden mit imap_fetchbody() abgerufen.

Die Funktion eignet sich besonders für E-Mail-Clients, Parser und automatisierte Postfach-Verarbeitung, bei denen man zwischen Text, HTML und binären Anhängen unterscheiden und diese separat behandeln muss.

Parameter

Name Typ Default Beschreibung
$imap Pflicht IMAP\Connection Eine aktive IMAP-Verbindungsressource, wie sie von imap_open() zurückgegeben wird. Ab PHP 8.1 ist dies eine IMAP\Connection-Instanz.
$message_num Pflicht int Die Sequenznummer der Nachricht im aktuellen Postfach (beginnend bei 1). Wird FT_UID als Flag gesetzt, wird dieser Wert stattdessen als UID interpretiert.
$flags int 0 Optionales Bitfeld. Einzig gültiger Wert ist FT_UID: Dann wird message_num als eindeutige UID statt als Sequenznummer behandelt.

Rückgabewert

Typ
stdClass|false
Beschreibung
Gibt bei Erfolg ein stdClass-Objekt zurück, das die MIME-Struktur der Nachricht beschreibt. Im Fehlerfall (z. B. ungültige Nachrichtennummer) wird false zurückgegeben. Bei Multipart-Nachrichten enthält das Objekt ein Array parts, dessen Elemente rekursiv dieselbe Struktur besitzen.

Beispiele

MIME-Typen und Teile einer Nachricht ausgeben

<?php
// Verbindung zum IMAP-Server herstellen
$imap = imap_open('{imap.example.com:993/imap/ssl}INBOX', 'user@example.com', 'geheim');

if ($imap === false) {
    die('Verbindung fehlgeschlagen: ' . imap_last_error());
}

// Struktur der ersten Nachricht abrufen
$structure = imap_fetchstructure($imap, 1);

if ($structure === false) {
    die('Struktur konnte nicht geladen werden.');
}

// Primären MIME-Typ ausgeben
// 0 = TEXT, 1 = MULTIPART, 2 = MESSAGE, 3 = APPLICATION, ...
echo 'Typ: ' . $structure->type . PHP_EOL;
echo 'Untertyp: ' . $structure->subtype . PHP_EOL;
echo 'Kodierung: ' . $structure->encoding . PHP_EOL;

// Bei Multipart: Teile durchlaufen
if (isset($structure->parts)) {
    foreach ($structure->parts as $index => $part) {
        echo 'Teil ' . ($index + 1) . ': ' . $part->subtype . PHP_EOL;
        if (isset($part->disposition) && strtolower($part->disposition) === 'attachment') {
            // Dateinamen aus Disposition-Parametern lesen
            foreach ($part->dparameters as $param) {
                if (strtolower($param->attribute) === 'filename') {
                    echo '  Anhang: ' . $param->value . PHP_EOL;
                }
            }
        }
    }
}

imap_close($imap);
Typ: 1 Untertyp: MIXED Kodierung: 0 Teil 1: PLAIN Teil 2: HTML Teil 3: PDF Anhang: rechnung.pdf

Anhänge einer Nachricht per UID extrahieren

<?php
function getAttachments(IMAP\Connection $imap, int $uid): array {
    $structure = imap_fetchstructure($imap, $uid, FT_UID);
    $attachments = [];

    if ($structure === false || !isset($structure->parts)) {
        return $attachments;
    }

    foreach ($structure->parts as $partNum => $part) {
        // Disposition prüfen
        $disposition = isset($part->disposition) ? strtolower($part->disposition) : '';
        if ($disposition !== 'attachment') {
            continue;
        }

        $filename = '';
        if (!empty($part->dparameters)) {
            foreach ($part->dparameters as $param) {
                if (strtolower($param->attribute) === 'filename') {
                    $filename = $param->value;
                }
            }
        }
        // Fallback: parameters nach name durchsuchen
        if ($filename === '' && !empty($part->parameters)) {
            foreach ($part->parameters as $param) {
                if (strtolower($param->attribute) === 'name') {
                    $filename = $param->value;
                }
            }
        }

        // Inhalt des Teils abrufen (Teilnummer = 1-basiert)
        $data = imap_fetchbody($imap, $uid, (string)($partNum + 1), FT_UID);

        // Dekodierung je nach Encoding-Typ
        if ($part->encoding === 3) { // BASE64
            $data = base64_decode($data);
        } elseif ($part->encoding === 4) { // QUOTED-PRINTABLE
            $data = quoted_printable_decode($data);
        }

        $attachments[] = [
            'filename' => $filename,
            'data'     => $data,
            'size'     => strlen($data),
        ];
    }

    return $attachments;
}

$imap = imap_open('{imap.example.com:993/imap/ssl}INBOX', 'user@example.com', 'geheim');
$attachments = getAttachments($imap, 12345);

foreach ($attachments as $att) {
    echo 'Datei: ' . $att['filename'] . ' (' . $att['size'] . ' Bytes)' . PHP_EOL;
    file_put_contents('/tmp/' . basename($att['filename']), $att['data']);
}

imap_close($imap);
Datei: rechnung.pdf (45231 Bytes)

// Wichtig · Fallstricke

Deprecation: Die IMAP-Erweiterung wurde in PHP 8.4 als veraltet markiert. Für neue Projekte wird empfohlen, auf aktiv gepflegte Bibliotheken wie ddeboer/imap oder den Symfony Mailer umzusteigen.

Typ-Konstanten: Der Wert type ist eine Integer-Konstante: TYPETEXT (0), TYPEMULTIPART (1), TYPEMESSAGE (2), TYPEAPPLICATION (3), TYPEAUDIO (4), TYPEVIDEO (5), TYPEMODEL (6), TYPEOTHER (7).

Encoding-Konstanten: encoding ist ebenfalls ein Integer: ENC7BIT (0), ENC8BIT (1), ENCBINARY (2), ENCBASE64 (3), ENCQUOTEDPRINTABLE (4), ENCOTHER (5).

Verschachtelte Multipart-Nachrichten (z. B. multipart/related innerhalb multipart/mixed) erfordern rekursive Verarbeitung der parts-Arrays; die Teilnummern für imap_fetchbody() werden dabei durch Punkte getrennt (z. B. "2.1").