IMAP и чтение писем хороших и разных с помощью PHP imap_fetchbody
Вот уж не думал, что что-то может добавить головняка больше чем регулярные выражения. Но нет, это может сделать попытка написать собственный php клиент для получения писем с ящика.
Суть проблемы: получаем письма с помощью imap_fetchbody, далее нам надо определить encoding. получаем мы такую простыню
stdClass Object
(
[type] => 1
[encoding] => 0
[ifsubtype] => 1
[subtype] => MIXED
[ifdescription] => 0
[ifid] => 0
[ifdisposition] => 0
[ifdparameters] => 0
[ifparameters] => 1
[parameters] => Array
(
[0] => stdClass Object
(
[attribute] => boundary
[value] => =-dsffdsfdsdsfsdf
)
)
[parts] => Array
(
[0] => stdClass Object
(
[type] => 1
[encoding] => 0
[ifsubtype] => 1
[subtype] => ALTERNATIVE
[ifdescription] => 0
[ifid] => 0
[ifdisposition] => 0
[ifdparameters] => 0
[ifparameters] => 1
[parameters] => Array
(
[0] => stdClass Object
(
[attribute] => boundary
[value] => =-ffdsfdsfdsfds
)
)
[parts] => Array
(
[0] => stdClass Object
(
[type] => 0
[encoding] => 2
[ifsubtype] => 1
[subtype] => PLAIN
[ifdescription] => 0
[ifid] => 0
[lines] => 1
[bytes] => 74
[ifdisposition] => 0
[ifdparameters] => 0
[ifparameters] => 1
[parameters] => Array
(
[0] => stdClass Object
(
[attribute] => charset
[value] => UTF-8
)
)
)
[1] => stdClass Object
(
[type] => 0
[encoding] => 3
[ifsubtype] => 1
[subtype] => HTML
[ifdescription] => 0
[ifid] => 0
[lines] => 3
[bytes] => 218
[ifdisposition] => 0
[ifdparameters] => 0
[ifparameters] => 1
[parameters] => Array
(
[0] => stdClass Object
(
[attribute] => charset
[value] => UTF-8
)
)
)
)
)
[1] => stdClass Object
(
[type] => 3
[encoding] => 3
[ifsubtype] => 1
[subtype] => OCTET-STREAM
[ifdescription] => 0
[ifid] => 1
[id] =>
[bytes] => 6850824
[ifdisposition] => 1
[disposition] => attachment
[ifdparameters] => 0
[ifparameters] => 1
[parameters] => Array
(
[0] => stdClass Object
(
[attribute] => name
[value] => =?UTF-8?B?0L/fdsfdsfdsfdsf=?=
)
)
)
)
)
мы знаем, что для корректной обработки тела письма нам необходимо получить encoding
Но, если для некоторых писем сработает $encoding=@$dsasdfs[1]->encoding;, то для других нужно будет $encoding=@$dsasdfs[0]->encoding; или например $encoding=@$dsasdfs[4]->encoding;
так как количество объектов всегда разное, и это зависит, судя по всему, от количества частей, из которых состоит письмо (вложения, их количество, тип текста письма, тип вложения и тп), то какие-либо попытки предсказать, по какому encoding нам ориентироваться для того, чтобы юзать
imap_utf8
imap_8bit
imap_binary
base64_decode
и некоторые другие функции, ломают вообще желание что-то делать. Реальный гуглёж на протяжении 5 часов ничего не дал по моей проблеме.
если кто-то реально делал такую же фигню и решил эту проблему - буду признателен за помощь.
Ответы (1 шт):
видимо, слишком сложный вопрос :) я все-таки нашел ответ спасибо @Makram приведу код здесь:
function getBody($uid, $imap) {
$body = $this->get_part($imap, $uid, "TEXT/HTML");
// if HTML body is empty, try getting text body
if ($body == "") {
$body = $this->get_part($imap, $uid, "TEXT/PLAIN");
}
return $body;
}
function get_part($imap, $uid, $mimetype, $structure = false, $partNumber = false) {
if (!$structure) {
$structure = imap_fetchstructure($imap, $uid, FT_UID);
}
if ($structure) {
if ($mimetype == $this->get_mime_type($structure)) {
if (!$partNumber) {
$partNumber = 1;
}
$text = imap_fetchbody($imap, $uid, $partNumber, FT_UID);
switch ($structure->encoding) {
case 3: return imap_base64($text);
case 4: return imap_qprint($text);
default: return $text;
}
}
// multipart
if ($structure->type == 1) {
foreach ($structure->parts as $index => $subStruct) {
$prefix = "";
if ($partNumber) {
$prefix = $partNumber . ".";
}
$data = $this->get_part($imap, $uid, $mimetype, $subStruct,
$prefix. ($index + 1));
if ($data) {
return $data;
}
}
}
}
return false;
}
function get_mime_type($structure) {
$primaryMimetype = array("TEXT", "MULTIPART", "MESSAGE", "APPLICATION",
"AUDIO", "IMAGE", "VIDEO", "OTHER");
if ($structure->subtype) {
return $primaryMimetype[(int)$structure->type] . "/" . $structure->subtype;
}
return "TEXT/PLAIN";
}
https://stackoverflow.com/questions/25503969/locate-html-and-plain-text-using-imap-fetchstructure