Чтение почты с помощью IMAP или POP3

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

Решение
Для решения этой задачи надо обратиться к расширению PHP IMAP, умеющему «разговаривать» и на языке IMAP, и на языке POP3:

// открываем IMAP-соединение
$mail = imap_open('{mail.server.com:143}', 'username', 'password');
// или открываем POP3-соединение
$mail = imap_open('{mail.server.com:110/pop3}', 'username', 'password');
// берем список всех почтовых заголовков
$headers = imap_headers($mail);
// берем объект заголовка для последнего сообщения в почтовом ящике
$last = imap_num_msg($mail);
$header = imap_header($mail, $last);
// выбираем тело для того же сообщения
$body = imap_body($mail, $last);
// закрываем соединение
imap_close($mail);

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


На самом деле в PHP есть 63 различные функции с именами, начинающимися словом imap, при этом не учитывается, что некоторые из них тоже понимают язык POP3 и NNTP.

Однако в своей основе разговор с почтовым сервером прост. Как и в случае применения многих других возможностей PHP, все начинается с открытия соединения и захвата дескриптора:

$mail = imap_open('{mail.server.com:143}', 'username', 'password');

В данном случае открываем IMAP-соединение с сервером по имени mail.server.com на порту 143. Одновременно в качестве второго и третьего аргументов передаются имя пользователя и пароль.

Для того чтобы открыть POP3-соединение, добавьте /pop3 к концу строки с именем сервера и номером порта. POP3 обычно работает на порту 110, поэтому после имени сервера надо добавить :110:

$mail = imap_open('{mail.server.com:110/pop3}', 'username', 'password');

Чтобы зашифровать ваше соединение с помощью SSL, добавьте /ssl в конце точно так же, как вы поступали с pop3. Необходимо также убедиться в том, что ваша инсталляция PHP собрана с конфигурационным параметром --with-imap-ssl, в дополнение к параметру --withimap.

Кроме того, саму системную библиотеку IMAP необходимо собрать с поддержкой SSL.


Если вы используете сертификат, подписанный самостоятельно, и хотите предотвратить неудачные попытки проверки его подлинности, добавьте также /novalidate-cert. Наконец,
большинство SSL-соединений общаются или через порт 993, или через порт 995. Все эти параметры могут располагаться в произвольном порядке, поэтому следующая запись имеет полное право на существование:

$mail = imap_open('{mail.server.com:993/novalidate-cert/pop3/ssl}',
'username', 'password');

Заключение переменной в фигурные скобки внутри строки в двойных кавычках, например {$var}, – это способ сообщить PHP, какую точно переменную следует интерполировать. Поэтому, чтобы передать интерполированную переменную в качестве первого параметра функции imap_open(), преобразуйте открывающую { в escape-последовательность:

$server = 'mail.server.com';
$port = 993;
$mail = imap_open("\{$server:$port}", 'username', 'password');

Открыв соединение, можно задавать почтовому серверу вопросы. Список всех сообщений в почтовом ящике можно получить, вызвав функцию imap_headers():

$headers = imap_headers($mail);

Она возвращает массив, каждый элемент которого представляет собой форматированную строку, соответствующую сообщению:

A 189) 5-Aug-2002 Beth Hondl an invitation (1992 chars)

Есть и альтернативный способ извлечения сообщения, который обеспечивают функции imap_header() и imap_body(), позволяющие извлечь заголовок объекта и строку тела:

$header = imap_header($message_number);
$body = imap_body($message_number);

Функция imap_header() возвращает объект с несколькими полями.


Самые полезные из них – поля subject, fromaddress и udate.

Элемент body – это просто строка, но если сообщение состоит из нескольких частей, например сообщение представлено и в виде простого текста, и в виде HTML-документа, то элемент $body содержит обе версии MIME-строки, описывающие их:

------=_Part_1046_3914492.1008372096119
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Plain-Text Message
------=_Part_1046_3914492.1008372096119
Content-Type: text/html
Content-Transfer-Encoding: 7bit
HTML Message
------=_Part_1046_3914492.1008372096119--

Чтобы избежать этого, вызывайте функцию imap_fetchstructure() в комбинации с функцией imap_fetchbody(). Это позволит выяснить, как отформатировано тело, и извлечь только требуемую часть:

// выбираем текст для сообщения $n
$st = imap_fetchstructure($mail, $n);
if (!empty($st->parts)) {
for ($i = 0, $j = count($st->parts); $i < $j; $i++) {
$part = $st->parts[$i];
if ($part->subtype == 'PLAIN') {
$body = imap_fetchbody($mail, $n, $i+1);
}
}
} else {
$body = imap_body($mail, $n));
}

Если сообщение состоит из нескольких частей, то переменная $st->parts содержит массив объектов, которые их описывают. Свойство part содержит целочисленное описание MIME-типа основного тела.

Оцените статью: (0 голосов)
0 5 0

Статьи из раздела PHP на эту тему:
Отправка почты
Отправка почты в кодировке MIME
Отправка сообщений в новостные группы Usenet
Поиск адресов с помощью LDAP
Поиск в DNS

Вернуться в раздел: PHP / 17. Интернет-службы