Что такое код imap_headers

Содержание

Что такое код imap_headers

(PHP 3, PHP 4, PHP 5)

imap_headerinfo — читает шапку/header сообщения.

Описание

object imap_headerinfo ( int imap_stream, int msg_number [, int fromlength [, int subjectlength [, string defaulthost]]])

Эта функция возвращает объект различных элементов шапки.

remail, date, Date, subject, Subject, in_reply_to, message_id,
newsgroups, followup_to, references

Recent — ‘R’, если последнее и видимо,
‘N’, если последнее и невидимо,
‘ ‘, если не последнее
Unseen — ‘U’, если невидимо И не последнее,
‘ ‘, если видимо ИЛИ невидимо и и последнее
Answered — ‘A’, если на него ответили,
‘ ‘, если не ответили
Deleted — ‘D’, если удалено,
‘ ‘, если не удалено
Draft — ‘X’, если отложено/draft,
‘ ‘, если не draft
Flagged — ‘F’, если установлен флаг,
‘ ‘, если флаг не установлен

Обратите внимание, что поведение несколько непарное. Если вы хотите знать, является ли сообщение Unseen, вы обязаны проверить на

Unseen == ‘U’ || Recent == ‘N’

toaddress (полный: строка, до 1024 символов)

to[] (возвращает массив объектов из строки To, содержащий):
personal
adl
mailbox
host

fromaddress (полный: строка, до 1024 символов)

from[] (возвращает массив объектов из строки From, содержащий):
personal
adl
mailbox
host

ccaddress (полный cc: строка, до 1024 символов)
cc[] (возвращает массив объектов из строки Cc, содержащий):
personal
adl
mailbox
host

bccaddress (полная bcc-строка, до 1024 символов)
bcc[] (возвращает массив объектов из строки Bcc, содержащий):
personal
adl
mailbox
host

reply_toaddress (полный reply_to: строка, до 1024 символов)
reply_to[] (возвращает массив объектов из строки Reply_to, содержащий):
personal
adl
mailbox
host

senderaddress (полный sender: строка, до 1024 символов)
sender[] (возвращает массив объектов из строки sender, содержащий):
personal
adl
mailbox
host

return_path (полный return-path: строка, до 1024 символов)
return_path[] (возвращает массив объектов из строки return_path, содержащий):
personal
adl
mailbox
host

udate (дата mail-сообщения в формате unix time)

fetchfrom (из строки, сформатировано для вмещения fromlength символов)

fetchsubject (строка темы, сформатированная для вмещения subjectlength символов)

Linux.yaroslavl.ru

Учебник РНР
Назад Вперёд

imap_headerinfo — читает шапку/header сообщения.

Описание

object imap_headerinfo ( int imap_stream, int msg_number [, int fromlength [, int subjectlength [, string defaulthost]]])

Эта функция возвращает объект различных элементов шапки.

remail, date, Date, subject, Subject, in_reply_to, message_id,
newsgroups, followup_to, references

Recent — ‘R’, если последнее и видимо,
‘N’, если последнее и невидимо,
‘ ‘, если не последнее
Unseen — ‘U’, если невидимо И не последнее,
‘ ‘, если видимо ИЛИ невидимо и и последнее
Answered — ‘A’, если на него ответили,
‘ ‘, если не ответили
Deleted — ‘D’, если удалено,
‘ ‘, если не удалено
Draft — ‘X’, если отложено/draft,
‘ ‘, если не draft
Flagged — ‘F’, если установлен флаг,
‘ ‘, если флаг не установлен

Обратите внимание, что поведение несколько непарное. Если вы хотите знать, является ли сообщение Unseen, вы обязаны проверить на

Unseen == ‘U’ || Recent == ‘N’

toaddress (полный: строка, до 1024 символов)

to[] (возвращает массив объектов из строки To, содержащий):
personal
adl
mailbox
host

fromaddress (полный: строка, до 1024 символов)

from[] (возвращает массив объектов из строки From, содержащий):
personal
adl
mailbox
host

ccaddress (полный cc: строка, до 1024 символов)
cc[] (возвращает массив объектов из строки Cc, содержащий):
personal
adl
mailbox
host

bccaddress (полная bcc-строка, до 1024 символов)
bcc[] (возвращает массив объектов из строки Bcc, содержащий):
personal
adl
mailbox
host

reply_toaddress (полный reply_to: строка, до 1024 символов)
reply_to[] (возвращает массив объектов из строки Reply_to, содержащий):
personal
adl
mailbox
host

senderaddress (полный sender: строка, до 1024 символов)
sender[] (возвращает массив объектов из строки sender, содержащий):
personal
adl
mailbox
host

return_path (полный return-path: строка, до 1024 символов)
return_path[] (возвращает массив объектов из строки return_path, содержащий):
personal
adl
mailbox
host

udate (дата mail-сообщения в формате unix time)

fetchfrom (из строки, сформатировано для вмещения fromlength символов)

fetchsubject (строка темы, сформатированная для вмещения subjectlength символов)

PHP imap_mail_move: что это правильный ID из imap_header использовать?

Так вот это imap_header свалка .

StdClass Object ([дата] => Вт, 11 июнь 2013 19:12:28 -0700 [Дата] => Вт, 11 июня 2013 19:12:28 -0700 [тема] => Счет на darnhippies.org форуме заблокирована [Тема] => Счет на darnhippies.org форуме заблокирован [message_id] => [toaddress] => webmaster@example.com [к] => Array ([0] => StdClass объекта ([сообщения] => веб-мастер [хост] => example.com)

Я пытался двигаться, используя в $header->Msgno качестве идентификатора сообщения, я полагаю , так как ни одно сообщение не переместились , что это не правильный идентификатор.

Так что я использую (в данном примере) $header->message_id как идентификатор сообщения , чтобы двигаться?

Я также попытался использовать полное имя входного почтового ящика, включая адрес сервера только потому что.

Я получаю следующие ошибки около 90% времени .

Ошибка: Array ([0] => ошибка протокола IMAP: Ошибка в командном IMAP-COPY: Недопустимый messageset [1] => Ошибка в командном IMAP-COPY: Недопустимый messageset)

Так как же мне найти правильный идентификатор сообщения?

Я знаю, я могу передать через запятую список идентификаторов, я просто пытаюсь переместить одно сообщение первым.

Джон, вы должны использовать посылая сообщения , UID чтобы убедиться , что вы ссылки на правильную электронную почту. Msgno представляет собой порядковый номер , который изменяется по мере добавили сообщения электронной почты и удаляются из почтового ящика. Вы получаете сообщение это UID в PHP ( с использованием библиотеки PHP IMap) с:

результирующий $ UID является уникальным в почтовом ящике навсегда.

При использовании UID для перемещения / чтения / все сообщение, вам нужно добавить параметр к параметрам, передаваемым в соответствующей функции, чтобы указать, что вы используете UID, а не msgno например:

$body = imap_fetchbody(*stream handle*, $uid, *mime-type*, FT_UID);

FT_UID это константа , которая сообщает библиотеку IMap , что второй параметр является UID не msgno .

Документация php.net довольно хорошо, когда речь идет о библиотеке IMap и стоит прочитать.

Incidently, то message_id должен быть уникальным для всех электронных писем по всему миру, если отправитель является удовлетворение соответствующих RFC,

В IMAP, каждое сообщение имеет два идентификатора: порядковый номер сообщения (который я принимаю msgNo в РНР), а также уникальный идентификатор (UID). Порядковый номер сообщения может меняться по мере добавлены сообщения и удаляются из почтового ящика, но UID является постоянным для жизни сообщения *.

Строка используется является «Message-Id» из заголовка Message-Id из электронной почты, который не может быть использован для перемещения сообщений (для одной стороны, это не обязательно уникальное). Если у вас есть UID, Вы должны быть в состоянии использовать imap_mail_move с флагом модификатора UID, чтобы переместить сообщение.

(Я не знаком с PHP API, но, возможно, вы можете передать UID флаг модификатор для message_header, чтобы получить UIDs там, в вашем наборе результатов.)

*: Пока UIDVALIDITY папки не меняется, что он должен не на хорошо себя серверы, пока папка не удаляется и создается заново с тем же именем.

Пример работающего кода с imap

28.01.2010, 15:04

Перевести пример кода на PHP
Здравствуйте! Только стал изучать данный язык, никак не могу понять работу с классами. Нужно.

Ребята подскажите пример кода
вообщем смысл данного кода должен заключаться в следующем, если текст длинной более например 15.

Пример кода для обучения PHP
Могу немного наглеть,но просто просьба,кому не жалко написанный код(не бойтесь,использовать не.

Покажите пример кода PHP с использованием сессий.
Приветствую. Подскажите, плиз, простой пример сессии для использования на страницах сайта для.

Подскажите пример кода для реализации следущего (php)
Нужно чтобы при выборе позиции из выпадающего списка, из БД брался текст соответствующей позиции в.

Протокол IMAP, или о том, как мы данные из писем вытаскивали

Электронная почта – это важнейший инструмент для обмена информацией и если вы её используете для работы, то наверняка сталкивались с ситуацией: на почту приходит письмо, в котором содержатся данные необходимые для обработки скрипом. Говорить мы будем о Яндекс почте – в этой статье я поделюсь с вами, дорогие читатели, опытом как достать письма из ящика, так же мы разберем вариант, когда в письме есть вложенный файл — как его обнаружить и в итоге скачать для дальнейших манипуляций над ним.

Сам я с этой задачей столкнулся достаточно давно, и тогда при наличии малого опыта работы c почтовыми программами Яндекса потратил массу времени и нервов для достижения требуемого результата. Первая моя ошибка заключалась в том, что, как многие веб-разработчики, я начел интенсивно искать похожие примеры в сети, но не воспользовался самой справкой (помощью) Яндекс. Да, там есть полезная информация, хотя её и очень мало, но она достаточно важная для написания такого рода скрипта (об этом будет ниже). На то время требовалось написать скрипт, суть которого сводилось: на Яндекс почту заказчика приходило письмо с прайсом товаров в xls формате раз в сутки, его необходимо было обработать (распарсить и сравнить с данными из БД интернет магазина и, в зависимости от результата, что-то обновить где-то, отключить или включить).

И первое, что мы сделаем перед написанием скрипта – это наметим наш план действий, который будет состоять из девяти пунктов:

  1. Настроим почту для получения доступа через почтовые протоколы;
  2. Наметим саму структуру PHP приложения и определимся с кодировкой файлов;
  3. Познакомимся с почтовым протоколом IMAP и его возможностями;
  4. Подключимся к Яндекс почте через логин и пароль аккаунта и отследим ошибки на этом этапе;
  5. Обработаем шапку письма;
  6. Получим и обработаем тела письма;
  7. Получим и сохраним вложенные файлы;
  8. Визуализируем проделанную работу;
  9. Сделаем выводы.

Тема довольно объёмная, но я постараюсь изложить всё максимально компактно и понятно. Пожалуй, приступим.

Настройка почты

Переходим в свою почту и заходим в настройки, как показано ниже на скриншоте:

Далее в нижнем правом углу находим ссылку «Почтовые программы» и кликаем по ней:

Теперь мы попали в настройки работы почты через протоколы IMAP и POP3:

Тут многие увидят картину как на изображение выше, но я сталкивался, и не один раз, когда доступы отключены. Поэтому если у вас настройки другие, ставим галочки как на скриншоте, для нас главное разрешить доступ через протокол IMAP.

Структура приложения и её кодировка

В этом примере мы не будем придумывать сложную структуру приложения, так как она не нужна, а добавим только то, что необходимо (я работаю в редакторе Sublime Text):

  • tmp – папка в которую будем загружать вложенные файлы из письма, если они есть;
  • .htaccess – настройка серверной части, если у вас сервер apache;
  • functions.php – сюда будем добавлять наши функции;
  • main.css – файл стилей;
  • index.php – точка входа приложения;

Кодировку будем использовать UTF-8 и поэтому сразу заполним файл .htaccess следующими строками:

Протокол IMAP

Возвращаясь к первому пункту видно, что работать с почтой Яндекс можно также и через протокол POP3. Так почему же именно IMAP? Из двух этих протоков IMAP является более новым и альтернативным POP3, следовательно, у него есть ряд преимуществ (их можно изучить, воспользовавшись википедией), но в нашем случае на выбор повлияло только то, что он более новый. Лично я особой разницы не вижу, что использовать под конкретную задачу получения письма. Если по какой либо причине вам потребуется использовать протокол POP3 то все функции, которые применимы к IMAP будут работать и для него.

Подключаемся к Яндекс почте при помощи протокола IMAP

Для того чтобы подключиться к почте нам нужно знать три параметра: логин почты, её пароль и адрес почтового сервера. Если с двумя параметрами проблем нет, то второй можно найти именно в помощи Яндекс. Об этом (возникшей у меня проблеме) я выше и писал в сети масса примеров, где третий параметр указан не правильно и, представьте себе, что уже на стадии подключения возникают ошибки – это, как минимум, неприятно. Я не буду ходить вокруг да около и сразу дам прямую ссылку на страницу Яндекс – настройка почтовых программ . Вот собственно что нам нужно для подключения:

Теперь можно переходить непосредственно к самому коду:

Первым делом дополнительно указываем кодировку UTF-8 при помощи заголовка и отключаем отображение ошибок. Подключаем файл functions.php и указываем настройки, о которых выше была речь. В массиве $mail_filetypes прописываем форматы файлов, которые нам нужны. Так было решено сделать, чтобы отсеять ненужный мусор, и получать конкретные файлы. Соединение с почтой происходит при помощи функции imap_open(), которая при удачном выполнении возвращает IMAP-поток, а при неудачном — false (но если включить отображение ошибок, то это не так). Завершаем работу с потоками при помощи функции imap_close() передав ей индикатор соединения. Между этими двумя функциями идёт обычный условный оператор.

При удачном соединении при помощи imap_num_msg() узнаем число писем на почте и добавляем массив, в который будем помещать все нам необходимые данные из потока. Далее следует цикл, в котором будет обрабатываться каждое письмо по его номеру (нумерация происходит от 1) по отдельности.

Обработка шапки письма

Для получения шапки письма необходимо воспользоваться функцией imap_header(), вторым параметром которой являет номер письма:

На данном этапе мы получим объект, из которого и будем вытягивать нужные нам данные, сохраняя в массив $mails_data. Вот пример одного из писем:

На этом скриншоте видно, что все данные дублируются, но это особой роли не играет, тянем, то, что удобнее. Намного важнее — кодировка темы письма. Она может быть какой угодно и этот момент надо контролировать. Такая же ситуация и с телом письма и с вложенными файлами.

Сохраняем в нашем массиве: временную метку, дату получения письма, email получателя и отправителя и переходим к получению темы письма. Для этого нам необходимо вначале добавить три функции в файл functions.php:

Названия говорящие и, я думаю, стоит пояснить только последнюю функцию. Она принимает закодированную строку и при помощи imap_mime_header_decode() декодирует ее, в результате чего возвращается массив объектов, у каждого из которых есть два свойства charset (кодировка) и text (текст темы). Дальше всё просто: в цикле проверяя кодировку, приводим к UTF-8 и склеиваем тему в единый заголовок и возвращаем его.

Теперь вернёмся в файл index.php и вытянем последний параметр:

На этом обработка шапки письма будет завершена.

Работаем с телом письма

Продолжаем постепенно формировать наш массив с обработанными данными письма и теперь для получения тела нам необходимо воспользоваться двумя функциями:

В первой переменной $msg_structure находится структура письма – это объект, в котором можно найти массу полезной информации, пример части этого объекта представлен ниже:

Что важно для решения нашей задачи:

  • type – первичный тип тела письма, в зависимости от того, что к нам приходит на почту он может меняться от 0 до 7 (каждой цифре советует свой вид контента который находиться в теле письма);
  • encoding – кодировка трансфера тела, меняется от 0 до 5 (0 — 7BIT, 1 — 8BIT, 2 – BINARY, 3 — BASE64, 4 — QUOTED-PRINTABLE, 5 — OTHER);
  • parts – массив частей письма, который соответствует структуре объекта уровнем выше.

Немного подробнее рассмотрим свойство parts. Первое, что нужно сказать это то, что в нулевой ячейке этого массива находиться информация, соответствующая именно тексту письма, а начиная с первого – вложенным файлам. Также в каждом объекте указывается type и в parameters кодировка в явном и в не явном виде.

Структура письма может быть сколько угодно вложенной, по крайне мере у меня были случаи, когда доходило до четырёх — пяти уровней, поэтому чтобы её, как говорится, раздраконить нам в дальнейшем потребуется написать рекурсивную функцию.

Вторая функция imap_fetchbody() извлекает определённую часть письма, чаще всего в закодированном виде.

Теперь добавим переменную, в которую будем сохранять обработанную версию тела письма:

Вернёмся в файл functions.php и напишем рекурсивную функцию:

Функция recursive_search() принимает один параметр – структуру письма, где последовательно проверяет свойства и достает три параметра: encoding, charset, subtype. Точкой выхода из рекурсии является отсутствие свойства parts с нулевой ячейкой. Больше пояснять тут особо нечего, из кода я думаю понятно, что и как происходит.

Добавим ещё одну функцию для переконвертации тела письма, которая нам потребуется в дальнейшем:

Двигаемся дальше и возвращаемся в файл index.php, где пишем следующий код:

После того, как мы получили данные из рекурсии, постепенно проверяем кодировку трансфера и, в зависимости от этого, вызываем функцию structure_encoding() с соответствующими параметрами. В последнем условном операторе учитываем, то, что мы работает в UTF-8 и если после всех манипуляций у нас получится отличное от кодировки, перекодируем.

Осталось подвести черту:

В теле письма может оказаться, как и обычный текст, так и HTML разметка со своими стилями. Кодируем в BASE64, чтобы при визуализации не поехала уже наша верстка.

Вложенные файлы

Вот, плавно подбираемся к концу написания нашего приложения:

Кусок, отвечающий за обработку вложенного файла гораздо меньше, а теперь — почему именно так. Принцип работы с файлом аналогичен работе с телом письма, только этот этап начинаем с наличия его в массиве свойства parts. Не забываем отсеивать ненужные, сверяясь со списком типов. При помощи нехитрой функции file_put_contents() мы сохраняем наш файл к себе на сервер в папку tmp.

Хочу увидеть результат!

В процессе работы у нас сформировался массив с данными $mails_data, и для визуализации мы уже будем работать непосредственно с ним. В этой статье я использовал тестовое письмо, которое лежало у меня почте, давайте глянем, что у нас получилось в итоге:

Вот какого вида примерно должен у вас получиться массив, увы, пришлось скрыть содержание файла по личным причинам. Теперь переходим к нашей HTML разметке:

Стили я не буду тут добавлять, так как они особой роли не играют, в итоге:

А на сервере в папке tmp у вас появится файл.

Заключение

Проделав все этапы из статьи, вы достигните должного результата, но всё не так просто, как может показаться – есть подводные камни, которые необходимо учитывать. При написании скрипта под конкретную задачу необходимо следить за кодировкой на всех этапах, письма могут идти с различных почт, у каждой из которых могут быть свои нюансы. Так же немаловажным будет учитывать, что Яндекс почта и их документация периодический обновляется, поэтому могут появиться различные подпункты для работы с почтовыми программами. На этом у меня всё, надеюсь вам пригодиться данная статья при работе с более низкоуровневым вариантом Яндекс почты.

Получение почты через IMAP в PHP

В PHP без проблем можно работать с почтой через IMAP, для этого есть все необходимые функции, подробнее на php.net.

Получение писем

Принцип работы следующий:

$imap = imap_open(«адрес», «e-mail», «пароль») – создает подключение к почтовому ящику. Далее, функция imap_search($imap, ‘ALL’) получает массив c индикаторами писем.

ALL Все сообщения
UNSEEN Непрочитанные сообщения
SEEN Прочтенные сообщения (установлен флаг seen)
NEW Новые сообщения (впервые появилось в ящике в ходе текущей сессии)
OLD Старые сообщения
ANSWERED Сообщения с флагом answered (отвеченный)
UNANSWERED Неотвеченные сообщения
DELETED Удаленные сообщения
UNDELETED Не удаленные сообщения
FLAGGED Сообщения с установленным флагом flagged (важное)
RECENT Сообщения с флагом recent (недавнее сообщение)
UNFLAGGED Сообщения без установленных флагов
ON «date» Сообщения с датой, равной « date »
BEFORE «date» Сообщения с датой, до « date »
SINCE «date» Сообщения с датой, после « date »
FROM «string» Сообщения в поле From: которых присутствует «string »
TO «string» Сообщения в поле To: которых присутствует «string »
SUBJECT «string» Сообщения, у которых присутствует «string » в поле Subject
BODY «string» Сообщения содержащие «string » в теле
TEXT «string» Сообщения с текстом «string »
KEYWORD «string» Сообщения с ключевым словом «string»
UNKEYWORD «string» Сообщения, не имеющие ключевого слова «string »

Далее массив обрабатывается в цикле, в примере происходит обход по всем письмам.

Как видно в примере, тема письма и другие данные закодированы в base64 ( ?UTF-8?B?SGVsbyBXb3JsZA==?= ), декодировать их можно с помощью функции mb_decode_mimeheader() .

$body = imap_body($imap, $num) – тело письма, обычный текст.

Может быть закодировано в quoted-printable (= D0=94=D0=BE=D0=B1=D1=80=D1=8B=D0=B9 ), раскодировать можно функцией quoted_printable_decode() .

Установка флагов

imap_setflag_full ($imap, $num, $flag) – установит письму флаг, возможны значения:

seen Сообщение прочитано
answered На сообщение отправлен ответ
flagged Сообщение отмечено как «важное»
deleted Сообщение отмечено как удалённое
draft Сообщение отмечено как черновик
recent Недавнее сообщение

Можно установить сразу несколько флагов, разделяя их пробелами.

В примере, письмам, у которых в теме письма есть слово «заявка» устанавливается флаг «важное».

Удаление писем

В цикле, письмо помечается функцией imap_delete() , после этого вызывается функция imap_expunge() , которая выполняет удаление всех помеченных писем.

АйТи бубен

Инструменты пользователя

Инструменты сайта

Содержание

Команды IMAP

Протокол IMAP (Internet Mail Access Protocol) описывается в RFC 2060.

В отличии от POP3, который просто скачивает входящие письма и сохраняет их локально, с IMAP вы работаете с почтой непосредственно на сервере

Как и POP3, протокол IMAP использует концепцию клиент-сервер с набором команд. С помощью команд осуществляется передача сообщений электронной почты от сервера клиенту. Клиент устанавливает для этой цели TCP-соединение с портом 143 на сервере. Далее сервер должен ответить специальным сообщением-приглашением.

В строке 1 показана команда на открытие сеанса с помощью telnet с портом 143 (порт IMAP по умолчанию). Строка 5 отображает приглашение, выданное сервером IMAP. В строке 6 клиентом задана команда закончить сеанс с сервером. Затем сервер посылает сообщение об окончании сеанса (строка 7) и закрывает соединение с клиентом.

Каждая команда, выдаваемая клиентом, предваряется уникальным идентификатором. Сервер может затем использовать этот идентификатор в своих ответах, что позволяет клиенту определить, к какой команде относится ответ сервера. Это особенно важно при выполнении сервером нескольких команд за сеанс. Идентификатор обычно представляет собой короткую строку алфавитно-цифровых символов, которая генерируется клиентом. Так, в строке 6 листинга 7.1 клиентом был выбран идентификатор a001. Если бы клиенту потребовалось задавать и другие команды, то следующим идентификатором был бы a002 и т.д. Часто для упрощения идентификаторы команд в течение сеанса IMAP просто последовательно увеличивают один из своих разрядов.

После установления соединения клиент находится в состоянии ожидания проверки подлинности, так как для выполнения каких-либо операций со своим почтовым ящиком на сервере он должен идентифицировать себя. После идентификации на сервере клиент может использовать команды IMAP для управления сообщениями на сервере. Протоколом IMAP предусмотрена возможность поддержки пользователем нескольких почтовых ящиков на одном сервере. При этом клиент может читать, отправлять и удалять сообщения в любом из принадлежащих ему почтовых ящиков.

Методы проверки подлинности пользователя в IMAP

Так же как и в протоколе POP3, в IMAP имеется несколько методов проверки подлинности клиента. Некоторые из них обеспечивают больший уровень безопасности, по сравнению с другими. В отличие от клиентов POP3, клиенты IMAP часто проводят довольно длительные сеансы с сервером при обработке сообщений. Таким образом, идентификатор пользователя и пароль не передаются по сети несколько раз в час, как это обычно происходит при работе по протоколу POP3.

Команда LOGIN

Команда LOGIN позволяет клиенту при регистрации на сервере IMAP использовать идентификатор пользователя и пароль в обычном текстовом виде.

Команда AUTHENTICATE

С помощью команды AUTHENTICATE клиент может использовать при регистрации на сервере IMAP альтернативные методы проверки подлинности. Индивидуальная проверка подлинности пользователей не является обязательной и поддерживается не всеми серверами IMAP. К тому же реализации такой проверки могут различаться в зависимости от сервера. Когда клиент выдает команду AUTHENTICATE, сервер отвечает на нее строкой вызова в кодировке base64. Далее в обязанности клиента входит ответ на вызов сервера о проверке подлинности, также закодированный base64. Если на сервере не поддерживается метод проверки подлинности, предложенный клиентом, он включает в свой ответ отрицательное слово NO. После этого клиент должен продолжить переговоры по согласованию метода проверки подлинности. Если все попытки определить метод проверки подлинности потерпели неудачу, то клиент предпринимает попытку зарегистрироваться на сервере посредством команды LOGIN. Пример сеанса с применением AUTHENTICATE:

В строках 6–9 показаны попытки клиента согласовать с сервером IMAP метод проверки подлинности. Как видите, все они не увенчались успехом. А в строке 10 показано, что метод проверки, приемлемый и для клиента, и для сервера, найден. Отвечая, сервер в строке 11 выдает кодированную строку с вызовом в кодировке base64. Однако в строке 12 клиент отвергает попытку регистрации и возобновляет ее лишь в строке 14 с помощью команды LOGIN.

Клиентская часть протокола IMAP

После регистрации на сервере IMAP клиент может приступить к манипулированию сообщениями. Протокол IMAP предлагает довольном много команд для чтения, перемещения и удаления почтовых сообщений в почтовых ящиках на сервере. Помните, что протокол IMAP предполагает хранение всех сообщений на сервере. Загрузка почтовых сообщений на локальный компьютер производится лишь для отображения. При этом они не перемещаются и не копируются на локальный ПК клиента.

Почтовый ящик для клиента по умолчанию носит название INBOX. Все новые сообщения ложатся именно в INBOX. Клиент имеет возможность создавать новые почтовые ящики (иногда называемые в программах-клиентах для работы с электронной почтой папками). Туда с целью упорядочения он может перемещать сообщения из папки INBOX.

Каждому сообщению назначается уникальный идентификатор (UID), по которому они идентифицируются в почтовом ящике. Метка UID сохраняется в течение всех сеансов IMAP для того, чтобы клиентское программное обеспечение могло правильно идентифицировать сообщения в почтовом ящике. Каждому почтовому ящику соответствует уникальный идентификатор достоверности (UIDVALIDITY). Метка UIDVALIDITY должна присутствовать во время всех сеансов IMAP, только в том случае, если идентификаторы сообщений в ящике оставались неизменными. Если в почтовом ящике имеются сообщения с различными идентификаторами, то значение UIDVALIDITY при следующем сеансе должно увеличиться. Это позволяет клиентам быстро определять, появились ли в почтовом ящике новые сообщения с момента последнего к нему обращения.

Каждое сообщение снабжается флагом, который отображает его статус. Флаг может быть постоянным или задаваться на время сеанса. Постоянные флаги могут изменяться клиентом и сохраняться вне зависимости от сеансов. Флаги, назначаемые на время сеанса, действительны только на время текущего сеанса IMAP. В табл. 7.1 представлены варианты флагов почтовых сообщений.

Флаги почтового сообщения IMAP

Почтовому сообщению может соответствовать 0 флагов или несколько флагов. Информация о флагах передается клиенту вместе с самим сообщением. В обязанности клиента входит интерпретация флагов соответствующим образом.

В следующем разделе описываются команды IMAP, которые клиент может задавать серверу.

Сервер должен отвечать соответствующим образом на заданные команды или отвечать отрицательно, если команда задана неправильно либо не поддерживается.

Команда SELECT

Команда SELECT используется, лишь когда почтовый ящик активен. По умолчанию, пока клиент не зарегистрирован в системе, ни один из принадлежащих ему почтовых ящиков не является выбранным. Далее клиент должен выбрать почтовый ящик, с которым он собирается работать. Обычно первый ящик, который выбирается клиентом, — это ящик INBOX, куда помещаются новые сообщения. Формат команды SELECT следующий:

Здесь mailbox — это название почтового ящика, к которому обращается клиент. Во время одного сеанса IMAP может быть активен только один почтовый ящик. Если ящик существует и у клиента имеется соответствующий доступ к нему, то сервер дает многострочный ответ, где описывается состояние почтового ящика.

Команда CREATE

Команда CREATE используется для создания нового почтового ящика на сервере IMAP. Имя и местоположение новых почтовых ящиков определяются в соответствии с общими спецификациями ОС Linux. В рабочем каталоге пользователя создается новый почтовый ящик с именем, но без задания местоположения, так как оно известно каталогу $HOME клиента. Например, если рабочий каталог клиента находится в /home/riley и клиент задает команду CREATE для создания нового почтового ящика stuff/junk, то вновь созданный ящик на почтовом сервере под управлением ОС Linux будет иметь путь /home/riley/stuff/junk. В этом примере вы видите, как используется знак разделителя /. Однако это не является общим для всех серверов IMAP.

Команда DELETE

Команда DELETE применяется к почтовым ящикам, а не к сообщениям. Сервер IMAP при получении этой команды попытается удалить почтовый ящик с именем, указанным в качестве аргумента команды. В аргументе команды можно использовать стандартное описание путей ОС Linux, со знаком разделителя /, если только они не находятся в каталоге $HOME. Сообщения из удаленных почтовых ящиков восстановлению не подлежат и теряются вместе с ящиками.

Команда RENAME

С помощью команды RENAME клиент может изменить имя почтового ящика. При этом возможно применение двух параметров. Первый параметр — собственно имя почтового ящика, который требуется переименовать. И второй параметр — новое имя почтового ящика.

Команда LIST

Команда LIST используется для получения списка всех почтовых ящиков клиента. С ней используются два параметра. Формат команды LIST приведен ниже:

Здесь reference — каталог, где находятся почтовые ящики. Если задается пустая строка вместо этого параметра («»), то почтовые ящики находятся в рабочем каталоге пользователя $HOME. Второй параметр mailbox является именем почтового ящика, который нужно просмотреть. Здесь допускается использование специальных символов, так же, как и при получении обычного списка каталогов, например группового символа (*). Если именем почтового ящика задана пустая строка («»), то сервер будет возвращать в качестве ответа иерархический разделитель (для Linux /) и имя корневого параметра.

Команда LSUB

Команда LSUB используется для устранения проблемы, которая описана для команды LIST. В отличие от команды LIST, с помощью которой отображается все содержимое рабочего каталога пользователя, с помощью команды LSUB отображаются лишь активизированные ранее описанной командой SUBSCRIBE почтовые ящики клиента. Параметры команды LSUB точно такие же, что и для команды LIST, т.е. ссылка (reference) и имя почтового ящика. Подобно команде LIST, параметр ссылки указывает путь к каталогу, в котором находятся почтовые ящики с соответствующими именами (каталог $HOME, если указано «»). Соответственно, под именем почтового ящика понимается имя ящика или имена ящиков, которые требуется вывести в списке (допускается групповой символ (*).

Почтовые ящики могут затем добавляться в список активных ящиков с помощью команды SUBSCRIBE, а удаляться из списка с помощью команды UNSUBSCRIBE. С помощью этих команд можно реализовать на базе клиента IMAP чтение групп новостей. При этом каждая группа новостей реализована как отдельный почтовый ящик на сервере, на которую затем можно подписаться. Сегодня большинство программ для работы с электронной почтой включают функцию чтения групп новостей, так что выполнение этих операций в IMAP не требуется.

Команда APPEND

APPEND — еще одна команда из семейства команд IMAP. Как правило, протокол IMAP применяется исключительно для чтения сообщений из почтовых ящиков. С помощью команды APPEND появляется возможность посылать сообщения в почтовый ящик, добавляя сообщение к концу файла почтового ящика. Эта функция работает не совсем корректно и она является довольно опасной, поэтому не рекомендуем увлекаться ею в качестве альтернативы SMTP. Это, скорее, приятное излишество протокола IMAP, а не рабочая лошадка. Основной формат команды APPEND следующий:

Команда CHECK

Команда CHECK используется для установки контрольной точки в почтовом ящике. Любые операции, такие, например, как запись данных из памяти сервера на его жесткий диск, должны выполняться при соответствующем состоянии почтового ящика. Именно для проверки целостности почтового ящика после дисковых и других подобных им операций и применяется команда CHECK. Эта команда используется без параметров.

Команда CLOSE

Команда CLOSE полностью соответствует своему названию — она закрывает почтовый ящик.

Действие команды CLOSE четко прослеживается на только что открытом новом почтовом ящике. Открытый почтовый ящик закрывается также с помощью команды LOGOUT. Команда CLOSE не имеет параметров.

Команда EXPUNGE

Ответ сервера на команду EXPUNGE представляет собой отчет о новом состоянии почтового ящика.

В строке 8 пользователь alex выбирает почтовый ящик с именем newbox. Строки 9–16 представляют собой ответ сервера с информацией относительно выбранного почтового ящика. Строка 9 говорит о том, что в нем находится 6 сообщений. В строках 17 и 20 пользователь alex воспользовался командой STORE, чтобы пометить два сообщения как удаленные (\DELETED). Затем в строке 23 пользователь alex выдает команду STATUS. Из строки 24 можно сделать заключение, что, с точки зрения сервера IMAP, в почтовом ящике все еще находятся шесть сообщений, хотя два из них помечены как удаленные. В строке 26 пользователь выдает команду EXPUNGE, по которой сообщения, помеченные как удаленные, стираются. Ответ сервера в строках 27–31 подтверждает, что сообщения были удалены из ящика и в нем осталось четыре сообщения. Это же подтверждает и команда STATUS, заданная в строке 32. На нее сервер отвечает, что в почтовом ящике теперь только четыре сообщения.

Команда SEARCH является одним из наиболее мощных средств из арсенала IMAP. С помощью этой команды производится поиск сообщений по критериям в активном почтовом ящике с последующим отображением результатов в виде номера сообщения. Формат команды SEARCH следующий:

Здесь CHARSET specification состоит из служебного слова CHARSET, за которым следует обозначение набора символов. Набор символов по умолчанию — ASCII , так что, как правило, этот параметр опускается. Параметр search criteria определяет ключевые критерии поиска и их значения. Критерии поиска описаны в табл. 7.3.

Таблица. Критерии поиска для команды SEARCH

Как видно из таблицы существует огромное количество критериев поиска сообщений. Это очень удобно, когда требуется найти специфическое сообщение в почтовых ящиках, которые заполнены большим количеством сообщений. Ниже представлен короткий пример с использованием команды SEARCH.

В строках 17, 20 и 23 показаны примеры использования команды SEARCH. Строки 18, 21 и 24 являются ответами сервера IMAP на команду SEARCH. В ответе содержатся номера сообщений, которые соответствуют критерию поиска. Если соответствий не найдено, то сервер возвращает слово SEARCH без идентификатора сообщения UID.

Команда FETCH

Команда FETCH используется для получения текста почтового сообщения. Она применяется только для отображения сообщений. В отличие от POP3, клиент IMAP не сохраняет копию сообщения на клиентском ПК.

Команда STORE

Команда STORE применяется для изменения информации о сообщении. Формат команды следующий:

Аргумент задает диапазон номеров сообщений, к которым применяется команда STORE. В настоящее время для этой команды определено только два типа данных ( ). Тип FLAGS определяет набор флагов, установленных для сообщения. Тип FLAGS.SILENT также определяет набор флагов, установленных для сообщения, но при этом сервер IMAP не возвращает их новое значение в своем ответе.

Поведением этих типов данных можно управлять, задав перед ними знак плюс (+) или минус (-). Знак плюс означает, что значение типа данных ( ) будет добавлено к сообщению, минус — что оно будет удалено из сообщения.

В строке 18 этого листинга показано, как устанавливается флаг \DELETED для сообщения в активном почтовом ящике с номером 1. Обратите внимание, что перед флагом задан знак плюс (+). Можно было бы также задать флаг (-). Тогда флаг \DELETED был бы отменен для сообщения (один из способов восстановить удаленное сообщение до того, как вступят в силу контрольные точки сообщения).

Команда COPY

Команда COPY используется для копирования сообщений из одного почтового ящика в другой. Формат команды COPY приведен ниже:

Здесь задает диапазон номеров сообщений, которые нужно скопировать из активного почтового ящика, а указывает имя ящика, в который их нужно скопировать.

Для протокола IMAP не определена команда перемещения сообщений, но очевидно, что эта операция есть не что иное, как копирование сообщений в другой почтовый ящик с заданием для оригиналов сообщений флага \DELETED. После следующей ротации почтового ящика (расстановки контрольных точек) оригиналы сообщений будут удалены, и останутся только их копии.

Команда CAPABILITY

С помощью команды CAPABILITY клиент может запрашивать у сервера IMAP информацию о его возможностях.

Команда NOOP

Действия команды NOOP, как мы знаем, соответствует ее названию, т.е. она ничего не делает. Она может применяться для поддержки активности во время сеанса для того, чтобы сеанс не прекратился по таймеру интервала ожидания. Ответ сервера на команду NOOP всегда должен быть положительным. Так как сервер часто в ответе возвращает состояние выполнения той или иной команды, то NOOP вполне можно использовать как триггер для периодического запроса о состоянии сервера. Если что-то произошло с почтовым ящиком во время периода ожидания, например сервер удалил сообщения согласно правилам, установленным для почтового ящика администратором почтовой системы, то в ответ на команду NOOP будет возвращена обновленная информация о его состоянии.

Команда LOGOUT

Команда LOGOUT используется для завершения сеанса для текущего идентификатора пользователя и закрытия всех открытых почтовых ящиков. Если какие-либо сообщения были помечены флагом \DELETED, то с помощью этой команды они будут физически удалены из почтового ящика.

IMAP: трудности перехода

Какие грабли зарыты в IMAP

Уже некоторое время IMAP работает в Почте Mail.Ru в полную силу, и я готов рассказать о том, с какими проблемами мы столкнулись при его запуске. Часть из них была связана с особенностями самого протокола и с его историей, другие были обусловлены спецификой взаимодействия IMAP с нашим хранилищем. Отдельная категория трудностей вызвана многообразием почтовых клиентов.

За подробностями — добро пожаловать под кат.

Нынешний запуск IMAP — наш второй подход к снаряду. В прошлый раз мы взяли сервер Dovecot и попробовали заточить его под себя. Результат нас не устроил: с нашими нагрузками и нашей инфраструктурой он сочетался плохо. В этот раз мы решили выбрать другой путь, и написали собственное решение.

IMAP мы запустили в мае, но анонсировали только в июне. Фактически, майская аудитория — это наши сотрудники и те пользователи, у которых клиенты автоматически определили наличие IMAP в нашей Почте и подключили к нему новые добавленные аккаунты.

Трудности, специфичные для протокола IMAP

1. Громоздкость самого протокола

Первая версия протокола IMAP появилась в 1986 году. В данный момент актуален стандарт IMAP версии 4rev1, который был обновлен в 2003 году. За такой долгий срок стандарт существенно разросся: его текущая версия насчитывает порядка 200 страниц.

Сейчас многие моменты, описанные в стандарте, устарели — в сегодняшних условиях они уже не являются необходимостью. Например, в протоколе предусмотрен возврат количества строк и MD5-суммы частей письма — функционал, который фактически не используется в современных клиентах.

Кроме того, существует множество опциональных расширений протокола. Некоторые из них, по сути, являются необходимыми для удобной работы с почтовым ящиком.

Чтобы побороть историческое наследие, нам пришлось реализовать несколько расширений. Одно из них — UID+: когда мы копируем или добавляем письмо, мы возвращаем ID нового письма, которое появилось на сервере в результате копирования или добавления. Это позволяет нам сэкономить на ресурсоемкой операции поиска, которую приходилось проводить клиенту, чтобы распознать, какое именно письмо было добавлено.

2. Отсутствие стандартного паттерна работы с сервером

IMAP предоставляет множество способов решить одну и ту же задачу и, как следствие, практически у всех клиентов паттерн работы различен. Также важно, что паттерны работы существенно отличаются от того, как работает веб-почта или POP3.

Более половины приходится на долю клиентов под устройства Apple: причина в том, что у них хорошо работает автоопределение IMAP. Outloook же, напротив, по умолчанию работает по POP3, и настраивать IMAP нужно руками.

Здесь можно выделить 2 основные категории: десктопные клиенты, которые сразу запрашивают информацию обо всех письмах в ящике или папке, и мобильные клиенты, которые изначально запрашивают информацию только о самых новых письмах. Далее нам оставалось изучить запросы, которые они делают, чтобы обновить состояние, как именно они вытягивают информацию о письмах.

Почему для нас это было необходимым шагом? При скромных нагрузках (например, если сервер обслуживает корпоративную почту небольшой компании) вопрос оптимальности стоит не так остро. Однако при наших объемах оптимальность становится критичной: следовательно, нам нужно было изучить паттерны работы всего зоопарка почтовых клиентов, обращающихся к хранилищу.

3. Количество одновременных сессий

По стандарту, минимальный таймаут сервера — 30 минут. Кроме того, один клиент может держать сразу несколько соединений к серверу (в протоколе не указано максимальное количество разрешенных соединений). Фактически, в нашем масштабе, это означает, что один сервер должен оптимально работать с десятками тысяч одновременных соединений. При работе в синхронном режиме такое количество соединений просто поглотило бы все ресурсы.

Для решения этой проблемы я написал библиотеку для асинхронной работы, построенную на базе edge-triggered epoll. Изначально я ставил перед собой задачу сделать библиотеку, при помощи которой можно было бы в будущем за пару дней написать свой асинхронный сервер для решения других задач, помимо IMAP; в результате практически весь код можно использовать для написания других сервисов.

4. Невозможность однозначно идентифицировать клиент

Наш сервер поддерживает расширение ID, которое позволяет нам идентифицировать примерно половину клиентов. К сожалению, другая половина об этом расширении не знает (из популярных можно назвать, например, Outlook).
Понимание того, с каким клиентом мы работаем, позволяет обойти его характерные баги, а также предсказать, каким будет паттерн работы в рамках данной сессии и, соответственно, оптимизировать работу. Для нас это критично, поэтому, если клиент не называет ID, мы стараемся идентифицировать его другими путями (в случае Outlook — по тегам).

5. Отсутствие команды перемещения сообщений

В клиентах перемещение реализовано через копирование+удаление. Нам, разумеется, хочется, чтобы при этом копия письма помещалась в нужную папку, а оригинал удалялся и не захламлял корзину. С другой стороны, иногда сам пользователь копирует письмо в новую папку, а затем удаляет оригинал: в этом случае удаленное письмо должно помещаться в корзину.
Чтобы различать эти два кейса, после копирования мы в этой же сессии помечаем письмо специальным внутренним флажком. Когда сам пользователь копирует письмо и удаляет оригинал, клиент, как правило, обновляет список писем. При обновлении флажок автоматически сбрасывается, а удаленное письмо оказывается в корзине. Если же письмо (в рамках перемещения) удаляет клиент, обновления не происходит, и письмо, помеченное флажком, удаляется окончательно.

Трудности, связанные с адаптацией текущего хранилища писем и индексов

1. Идентификация сообщений

Для работы по IMAP необходимо было поддержать два вида идентификаторов сообщений: порядковый номер, который может отличаться от сессии к сессии, а также уникальный номер, который сохраняется на все время жизни сообщения. Оба идентификатора должны удовлетворять довольно строгим критериям, которые не соответствовали схеме, используемой веб-почтой и POP3-сервером.

Наиболее рациональным оказывается держать в оперативной памяти весь набор порядковых номеров, их соответствие внутренним идентификаторам, а также IMAP ID. При открытии папки мы вытягиваем из хранилища список всех писем, наши внутренние идентификаторы, IMAP ID, флажки и размер сообщения — все то, что хочется отдавать без лишних запросов.

Обо всех изменениях порядкового номера в рамках одной сессии мы должны оповещать клиент. Согласно стандарту, последовательность IMAP ID должна соответствовать последовательности порядковых номеров. Порядковые номера мы получим, отсортировав список писем по уникальным номерам. Когда клиент выдает новую команду, мы заново открываем соединение с хранилищем, запрашиваем время последних изменений, которые были сделаны в ящике. Если изменений со времени последнего такого запроса не было, то мы просто возвращаем ответ на команду. В ином случае мы заново запрашиваем список сообщений в папке и сравниваем с аналогичным списком клиента. Далее мы либо возвращаем информацию об изменениях, либо, если протокол не позволяет этого сделать сразу, делаем у себя пометку о том, что письмо удалено, и ждем подходящего момента, чтобы сообщить об этом клиенту.

Из-за такой специфики — письма уже нет в ящике, но клиент об этом еще не узнал — клиент может запросить данные об уже удаленном письме. Более того, некоторые из них испытывали серьезные проблемы, если ответа на их запрос не поступало. Чтобы клиент не ломался, мы в ответ на подобные запросы возвращаем заглушки. Клиент получает нужную ему для нормальной работы информацию, а уже при следующем обновлении списка писем (оно, как правило, происходит сразу же) удаляет из него сообщение.

2. Необходимость оптимально возвращать информацию о MIME-структуре письма

Практически все клиенты запрашивают информацию о структуре письма. Часто в рамках первой сессии они запрашивают такую информацию сразу обо всех письмах в папке. Парсить письмо на каждый такой запрос было бы крайне неоптимально.
Вместо этого мы сделали кэш MIME-структур. Наличие кэша помогло нам побороть сразу несколько трудностей, связанных с особенностями IMAP — в частности, отсутствие стандартного паттерна работы с сервером: поскольку часть информации хранится в кэше, это помогает нивелировать нагрузку, связанную с разными паттернами работы клиентов.

Сейчас мы кэшируем до 50 сообщений. Почему не 2-3? Дело в том, что некоторые клиенты сначала запрашивают структуру письма, а потом тело, причем сразу для нескольких сообщений; максимальное число писем в такой «пачке» обычно составляет 50 штук.

3. Оптимальная отдача частей письма

Часто клиенты просят лишь текстовые части письма, которые могут находиться в конце самого сообщения. Для отображения сниппетов клиенты могут просить текстовые части сразу у 50-200 писем. Читать весь файл сообщения целиком (и обрабатывать 10 МБ письма для того, чтобы отдать 10 КБ текста) при этом не хочется; использовать индекс для определения позиции части внутри файла при каждом запросе также было бы накладно. В этой ситуации также спасает кэш структуры письма.
Преимущества такого подхода особенно наглядны тогда, когда клиент подгружает сниппеты для нескольких десятков писем: если бы мы не использовали кэш структуры, то для этого приходилось бы просмотреть много мегабайт и пожертвовать скоростью.

Для экономии места в наших хранилищах base64-части хранятся в декодированном виде внутри письма: при работе с веб-почтой это позволяет отдавать аттачи без лишнего перекодирования. Нужно было сделать схему отдачи частей с учетом этого перекодирования. Мы написали потоковое перекодирование на IMAP-сервере. Здесь также помог кэш — благодаря ему мы без перечитывания структуры можем понять, в каком виде (бинарном или нет) хранится тот или иной фрагмент.

4. Особенности работы некоторых клиентов

Некоторые клиенты не полностью соответствуют стандарту RFC: например, стандартные клиенты Android версий 2.2 — 2.3 не могут корректно отображать письма без возврата некоторых необязательных полей. Основная трудность заключалась в том, чтобы определить, какие именно поля каждый из таких клиентов считает для себя обязательными: приходилось решать это методом перебора.

Выше уже упоминалось о том, что у клиентов могут быть различные подходы к удалению писем: одни перемещают их в корзину, другие — удаляют сразу и безвозвратно. При этом некоторые клиенты не понимают стандартное расширение XLIST, которое мы поддерживаем, позволяющее определить, какая именно папка является корзиной. Вместо этого они используют в качестве корзины свою папку (так себя ведет, например, Sparrow).

Интересно ведет себя Outlook: по команде удаления письма не перемещаются в корзину, а помечаются как перечеркнутые, и затем удаляются позже. Выяснилось, что для пользователей это выглядит, как баг — многие просто не понимают, что делать дальше и как добиться того, чтобы клиент вел себя привычным образом и письма оказались в корзине.

В условиях такого разнообразия нам также было необходимо эмпирически понять, как ведет себя каждый из клиентов, и подстроиться под эти варианты — причем таким образом, чтобы пользователь мог быть уверен: независимо от того, в каком клиенте он работает, почта отреагирует на его действия привычно и предсказуемо (в данном случае — удаленное письмо окажется к корзине). Решали мы это, пробуя различные ответы через тестовый прокси-сервер и отслеживая реакцию клиента на каждый из вариантов.

То, что мы вынесли для себя: IMAP — достаточно «развесистая» штука, с множеством исторических особенностей, нажитых за 26 лет, которые умножаются на разнообразие почтовых клиентов. При наших нагрузках это выливается в то, что брать готовое решение и пытаться заточить его под себя нерационально: в лучшем случае объем работы будет таким же, как при самостоятельной разработке решения. Этим путем мы и пошли :)

Производительность: imap_headers () или imap_fetchheader ()?

У меня есть необходимость скачать все заголовки в почтовом ящике (тело не понадобится). Почтовый ящик может иметь 100k сообщений или более.

imap_headers () обещает вернуть все заголовки для почтового ящика; что сделает вещи простыми в использовании. У меня есть опасения, хотя о том, будет ли это будет performant через диапазон серверов IMAP там (и некоторые не давая все заголовки).

Альтернативой является использование imap_search() для получения списка идентификаторов, а затем imap_fetchheader () для итерации и получения всех заголовков (вероятно, используя какую-то систему очереди).

Кто-нибудь сталкивался с этой проблемой? Если imap_headers» работает » надежно (или есть простой способ сказать, что это не удалось), то это было бы предпочтительно; в противном случае я думаю, что imap_fetchheader-это путь.

1 ответ

Ни один из них не будет хорошо работать при любых обстоятельствах. Неправильно запрашивать заголовки всех сообщений в почтовом ящике, который содержит несколько тысяч или, возможно, сто тысяч сообщений od. С другой стороны, обработка их один за другим также не является разумной, так как библиотека, которую вы используете, является синхронной, и, следовательно, вы будете ограничены по времени между хостом, на котором работает ваш PHP-скрипт, и сервером IMAP, который вы запрашиваете.

Получите асинхронную библиотеку IMAP и используйте некоторое окно разумного размера/диапазон сообщений для выборки. Например. получение нескольких десятков или нескольких сотен сообщений каждый раз, вероятно, разумно.

Что такое код imap_headers

Помогите, необходимо посмотреть письма в ящике
Пробую так

Заголовки выводятся в таком виде:

Вместо русских символов кракозябра, что надо сделать, чтобы заголовки нормальными были ?
Спасибо

С ИМАП не работал, а насчет читаемости. Могу только предположить, что у тебя какие-то проблемы с кодировками. Судя по заголовкам, что ты показываешь, там UTF-8. А на странице какая кодировка?

* Обучаю PHP, JS, вёрстке. Интерактивно и качественно. За разумные деньги.

* «накапливаю умение телепатии» (С) и «гуглю за ваш счет» (С)

Илон Маск рекомендует:  Goto - Ключевое слово Delphi
Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL