Чтение новостей из Usenet

Задача
Требуется читать новости сети Usenet с помощью протокола NNTP, чтобы разговаривать с сервером новостей.

Решение
Для этого применяется расширение PHP IMAP. Оно также понимает протокол NNTP:

// открываем соединение с nntp-сервером
$server = '{news.php.net/nntp:119}';
$group = 'php.general'; // main PHP mailing list
$nntp = imap_open("$server$group", '', '', OP_ANONYMOUS);
// получаем заголовок
$header = imap_header($nntp, $msg);
// извлекаем поля
$subj = $header->subject;
$from = $header->from;
$email = $from[0]->mailbox."@".$from[0]->host;
$name = $from[0]->personal;
$date = date('m/d/Y h:i A', $header->udate);
// получаем тело
$body = nl2br(htmlspecialchars(imap_fetchbody($nntp,$msg,1)));
// закрываем соединение
imap_close($nntp);

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

// открываем соединение с nntp-сервером
$server = "{news.php.net/nntp:119}";
$group = "php.general";
$nntp = imap_open("$server$group",'','',OP_ANONYMOUS);

Функция imap_open() принимает четыре параметра.


Первый определяет сервер новостей и новостную группу, которую требуется прочитать.

В данном случае в качестве сервера выступает news.php.net – сервер новостей, который является зеркалом всех почтовых списков PHP. Благодаря добавлению /nntp расширение IMAP «понимает», что вы читаете новости, а не почту, и определяет номер порта, 119 (типичное значение порта, зарезервированное за протоколом NNTP). NNTP означает
транспортный протокол сетевых новостей (Network News Transport Protocol). Он применяется для организации взаимодействия серверов новостей точно так же, как HTTP является протоколом взаимодействия веб-серверов. Группой здесь является php.general – основной почтовый список сообщества PHP.

Средние два параметра функции imap_open() – это имя пользователя и пароль, на случай, если потребуется провести идентификацию вашей личности. Поскольку сервер news.php.net открыт на чтение для всех, оставьте эти параметры пустыми. Наконец, передайте флаг OP_ANONYMOUS, который сообщает IMAP, что вы анонимный читатель; сервер не будет делать запись о вас в специальном файле .newsrc.

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


Ниже приведена программа, отображающая недавние сообщения:

// читаем и показываем почтовый каталог
$last = imap_num_msg($nntp);
$n = 10; // показываем 10 последних сообщений
// заголовок таблицы
print <<




EOH;
// сообщения
for ($i = $last-$n+1; $i <= $last; $i++) {
$header = imap_header($nntp, $i);
if (! $header->Size) { continue; }
$subj = $header->subject;
$from = $header->from;
$email = $from[0]->mailbox."@".$from[0]->host;
$name = $from[0]->personal ? $from[0]->personal : $email;
$date = date('m/d/Y h:i A', $header->udate);
print <<
EOM;
}
// нижний колонтитул таблицы
echo "
Subject Sender Date
$subj $name $date
\n";

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


Поэтому чтобы извлечь последние $n сообщений, выполните цикл от $last-$n+1 до $last.

Внутри цикла вызовите функцию imap_header() для получения информации о почтовом сообщении, содержащейся в заголовке. Заголовок содержит всю метаинформацию, но не фактический текст сообщения; он хранится в теле. Заголовок, как правило, значительно меньше тела, это позволяет быстро получить информацию о многих почтовых сообщениях.
Теперь передайте функции imap_header() два параметра: дескриптор соединения с сервером и номер сообщения.

Вот некоторые самые полезные поля: size, subject, перечень from и udate. Свойство size представляет размер сообщения в байтах; если оно равно нулю, то сообщение было либо удалено, либо убрано каким-либо другим способом. Поле subject показывает тему сообщения. Перечень from – более сложное свойство. Это массив объектов; каждый элемент
массива содержит объект с тремя свойствами: personal, mailbox и host. Поле personal хранит имя отправителя: Homer Simpson. Поле mailbox представляет часть адреса электронной почты, находящуюся перед символом «@», – homer. Свойство host – это часть почтового адреса после знака «@» – thesimpsons.com.


Обычно в списке from находится только
один элемент, поскольку, как правило, сообщение имеет одного отправителя.
Присвоим переменной $from объект $header->from, т. к. PHP не имеет прямого доступа к $header->from[0]->personal из-за массива в середине структуры. Затем объединяем $from[0]->mailbox и $from[0]->host в форме почтового адреса отправителя. Применяем тернарный оператор для присвоения полю personal имени отправителя, если это поле определено, в противном случае берем почтовый адрес.

Поле udate содержит время отправки почты в виде метки даты/времени UNIX. Для преобразования значения поля из секунд в более дружественный для человека формат применяется функция date().

Конкретное почтовое отправление можно просмотреть следующим образом:

// читаем и показываем одно сообщение
$header = imap_header($nntp, $msg);
$subj = $header->subject;
$from = $header->from;
$email = $from[0]->mailbox."@".$from[0]->host;
$name = $from[0]->personal;
$date = date('m/d/Y h:i A', $header->udate);
$body = nl2br(htmlspecialchars(imap_fetchbody($nntp,$msg,1)));
print <<






From: $name <$email>
Subject: $subj
Date: $date
$body

EOM;

Код для извлечения единственного сообщения подобен коду для получения последовательности заголовков сообщения.


Основное отличие состоит в том, что вы определяете переменную $body, представляющую собой результат работы цепочки из трех функций. Самая внутренняя функция, imap_fetchbody(), вызывается для получения тела сообщения; она принимает те же параметры, что и функция imap_header(). Тело сообщения передается функции htmlspecialchars(), преобразующей в escape-последовательность любой HTML-элемент, который может пересечься с вашими. Затем ее результат передается функции nl2br(), конвертирующей все символы возврата каретки в теги XHTML
; теперь сообщение должно выглядеть на веб-странице правильно.

Чтобы прервать соединение с IMAP-сервером и закрыть поток, передайте функции imap_close() дескриптор IMAP-соединения:

// по окончании закрываем соединение
imap_close($nntp);

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

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

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