Zpracování přílohy emailu v PHP přes IMAP
Petr Wiedemann, 26. prosinec 2009
Následující krátký kód používám pro strojové zpracování příloh z emailu. Tento kód si neklade za cíl být univerzální. V mém případě zpracovává zprávy, které mají vždy stejnou strukturu.
Zprávy, ve kterých hledám informace nejprve třídí mailserver podle pravidel. V mém případě do podložky složky INBOX.
<?php
// Pripojeni k IMAP serveru.
$mbox = imap_open('{localhost:143/notls}INBOX/Data', 'username', 'password');
if ($mbox === false)
{
echo imap_last_error();
die();
}
// Vyhledani vsech nesmazanych zprav v otevrene slozce.
$mfound = imap_search($mbox, 'ALL UNDELETED', SE_UID);
if ($mfound === FALSE)
{
echo 'Zadne nesmazane zpravy ve slozce <strong>INBOX/Data</strong>.';
}
else
{
// Mame k dispozici pole s ID zprav. Pro kazdou nacteme jeji strukturu.
foreach ($mfound as $msg_id)
{
$msg_struct = imap_fetchstructure($mbox, $msg_id, FT_UID);
// Zajimaji nas pouze zpravy, ktere maji 2 a vice casti.
// Tyto zpravy mohou obsahovat prilohy.
if (isset($msg_struct->parts) && count($msg_struct->parts) >= 2)
{
// Vyhledani priloh v kazde casti zpravy.
for ($part_no = 0; $part_no < count($msg_struct->parts); $part_no++)
{
// Kontrola, jestli tato cast zpravy obsahuje parametry pro dalsi hledani.
if ($msg_struct->parts[$part_no]->ifdparameters)
{
// Prohledani parametru. Zajima nas atribut s nazvem 'filename'.
foreach ($msg_struct->parts[$part_no]->dparameters as $part_param)
{
// Tato cast obsahuje informaci o jmenu souboru v priloze.
if (mb_strtolower($part_param->attribute, 'utf-8') == 'filename')
{
// Kontrola, jestli ma soubor pozadovanou priponu.
if (pathinfo($part_param->value, PATHINFO_EXTENSION) == 'zpt')
{
// Nacteni obsahu casti mailu.
$part_content = imap_fetchbody($mbox, $msg_id, $part_no + 1, FT_UID);
// Dekodovani obsahu pokud je v BASE64 nebo jako QUOTED-PRINTABLE
switch ($msg_struct->parts[$part_no]->encoding)
{
case 3:
$part_content = base64_decode($part_content);
break;
case 4:
$part_content = quoted_printable_decode($part_content);
break;
}
// V promenne $part_content je obsah souboru v priloze.
// Na tomto miste by melo byt volani funkce pro zpracovani dat.
}
}
}
}
}
}
// Oznaceni zpravy ke smazani
imap_setflag_full($mbox, $msg_id, '\\Deleted', ST_UID);
}
}
imap_close($mbox);
?>
Po spuštění skript vyhledá ve složce všechny zprávy, které nejsou označeny ke smazání. U každé nalezené zprávy načte její strukturu. V případě, že zpráva obsahuje 2 nebo více částí, pokračuje v prohledání všech částí. Tento skript hledá data pouze v poli dparameters. Pokud nalezne parametr filename, načte jeho hodnotu, kterou je název souboru v příloze. V případě, že se jedná o hledaný typ souboru, načte obsah této části zprávy, kterou následně dekóduje, pokud je ve zprávě uložena jako BASE64 nebo QUOTED-PRINTABLE. Tento obsah následně předá třídě, která data dále zpracuje. Poslední věcí, kterou skript se zprávami provede, je jejich označení ke smazání.