Информационные технологииStfw.Ru 🔍

Чтение почты через Web-интерфейс.

В последнее время довольно популярными стали почтовые системы с web-интерфейсом.
🕛 06.12.2006, 13:47
Надо заметить, это довольно удобно, особенно для пользователей,
которые выходят в интернет с разных машин.
Для написания оной программы необходима библиотека

mail::pop3client

Назначение библиотеки очевидно - видно из названия.
В ней содержатся методы доступа к почтовому ящику pop3.
Простейший набор кода для проверки почтового ящика на наличие сообщений выглядит так:

use mail::pop3client;
$login = "mailuser";
$password = "parol";
$mailserver = "mail.server";
$pop = new mail::pop3client( user => $login,
password => $password,
host => $mailserver );
print "В вашем почтовом ящике ",$pop->count()," сообщений.<br>\n";

Все вообщем, просто:
Создать соединение;
Посчитать количество писем.
Первый пункт реализуем созданием объекта $pop,
второй - вызовом метода count() сего объекта.
Метод count() еще имеет одну особенность - если он возвращает -1,
то соединение не было создано, иными словами, не удалось соединиться с сервером.
Если мы в вышеуказанном коде последнюю строчку заменим на

if ($pop->count() == -1 ) { 
print "Не удалось соединиться с сервером!<br>\n"; 
} else { 
print "В вашем почтовом ящике ",$pop->count()," сообщений.<br>\n"; 
} 

, то выглядеть наш скрипт будет несколько приличнее (как-никак, обработка нештатной ситуации:).
Если этот код заработал, то нужно развивать успех.
Итак, методы класса
pop3client:new( user => 'user', password => 'password', host => 'host',
port => 110, debug => 0, auth_mode => 'best', timeout => 60 )
Это конструктор класса. Разработчики библиотеки настоятельно рекомендуют
пользоваться объекным стилем написания. Аргументы метода следующие:
user = имя пользователя
password = пароль
host = почтов?й сервер
port = порт
debug = если этот параметр равен 1, то в stderr выводится трафик сокета
auth_mode = допустимые значения:'best', 'pass' and 'apop'
timeout = число по умолчанию - 60 сек.
head( message_number )
Возвращает заголовок письма с номером message_number.
Результат = строка или массив, в зависимости от контекста.
Поддерживается не всеми pop3 серверами. body(message_number)
Возвращает тело письма с номером message_number.
Результат = массив строк или массив, в зависимости от контекста. delete( message_number )
Помечает сообщение на удаление.
Удаляется после выполнения команды quit. До удаления можно отменить методом reset.
close
Закрыть соединение.
count
Возвращает количество сообщений в почтовом ящике.
Нет цели подменять этой статьей описание библиотеки,
поэтому ограничимся только этими описаниями.
В библиотеке mail::pop3client методов примерно в 2 раза больше,
и прочитать его описание в первоисточнике несколько полезней,
тем более, что для начала работы достаточно и вышеперечисленных методов.
Теперь было бы неплохо просмотреть список сообщений на сервере, от кого, тема.
Для этого сосчитаем сообщения и в цикле выведем их заголовки:

. 
print "В вашем почтовом ящике ",$pop->count(),"сообщений<br>\n"; 
for( $i = 1; $i <= $pop->count(); $i++ ) { 
foreach( $pop->head( $i ) ) { 
/^(from|subject):\s+/i && print $_, "<br>\n"; 
} 
} 
#закрыть соединение 
$pop-close(); 

Если заработала и сия конструкция, значит все делается правильно,
и можно переходить к написанию модуля просмотра сообщений.
Просмотреть сообщение №КАКОЙ_ТО можно, вытащив его методом body(№).
Поскольку метод нам вернет массив, то обыкновенным циклом foreach просмотрим письмо.
Вот текст процедуры просмотра тела письма:
sub get_body { 
$numb_mess = shift; 
foreach ($pop->body($numb_mess)) { 
print $_,"<br>\n"; 
} 
} 

Ну, а дальше - дело вкуса, как выбирать сообщение.
Я предлагаю сделать ссылочку на тему письма для просмотра оного.
Полный листинг сего "шедевра" расположен ниже:
use mail::pop3client; 
print "content-type:text/html\n\n"; 

$login = "mailuser"; 
$password = "parol"; 
$mailserver = "mail.server"; 

# Пробуем прочесть переданные параметры 
# Этот способ работает только с методом get!!! 

$temp=$env{'query_string'}; 

# Разбор строки параметров 

if ($temp ne '') 
{ 
@pairs=split(/&/,$temp); 
foreach $item(@pairs) 
{ 
($key,$content)=split (/=/,$item,2); # Режем на название ключа и значение. 

# Названия параметров и значения помещаем в хэш 

$data{$key}=$content; 
} 
} 

# Открываем соединение 

$pop = new mail::pop3client( user => $login, 
password => $password, 
host => $mailserver ); 

# Если был передан параметр view со значением, то просматриваем 
# сообщение с номером view 

if ($data{'view'} ne '') 
{ 
&get_body($data{'view'}); 
} 
else 
{ # Не было параметров 
print "В вашем почтовом ящике ",$pop->count()," сообщений.<br>\n"; 
for( $i = 1; $i <= $pop->count(); $i++ ) 
{ 
foreach( $pop->head( $i ) ) 
{ 
/^(from|subject):\s+/i && print "<a href="$script_name?view=$i">",$_, "</a><br>\n"; 
} 
} 
#закрыть соединение 
} 

$pop->close(); 

#Процедура просмотра сообщения 

sub get_body 
{ 
$numb_mess = shift; 
foreach ($pop->body($numb_mess)) 
{ 
print $_,"<br>\n"; 
} 
} 

Вот собственно и все. На самом деле я не советую выкладывать сей перл в интернет.
Его можно юзать на localhost-е. Почему?
Потому что в теле программы находятся значения логинов/паролей, а этого допускать не стоит.
Лучше наваять форму с парой полей, и передавать их методом post этому скрипту.
Прочесть строку параметров при передаче методом post можно кострукцией:

if ($env{'request_method'} eq 'post') { 
read(stdin,$temp,$env{'content_length'}); 
} 

т.е. читать нужно из стандартного потока ввода. Разбор строки точно такой же, как и в методе get.
Для дальнейшей работы с почтовым ящиком пару логин/пароль можно сохранить
в скрытом поле или в cookie с периодом устаревания ,например, пол-часа.
Далее, первым делом после печати строки content-type:text/html\n\n, прочтем сей куки:

$cookie = $env{'http_cookie'};

дальше его разбираем, как нам угодно. Я предлагаю следующую реализацию:

if ($data{'login'} and $data{'password'}) { 
# Запомним пароль/логин в куки в виде строки: 
# login::password, время устаревания = 1 час. 

print "set-cookie: login=$form{'login'}::$form{'password'}; expires=+1h;"; 
print "content-type:text/html\n\n"; 

# попытка создать соединение с pop3 сервером 

$pop = new mail::pop3client( user => $data{'login'}, 
password => $data{'password'}, 
host => $mailserver );} else { 
print "content-type:text/html\n\n"; 
$cookie = $env{'http_cookie'}; 

# Разбираем строку, полученную из cookie 

if ($cookie =~ "login") { 
($nm,$vals) = split(/=/,$cookie); 
($login,$passwd) = split(/::/,$vals); 
$pop = new mail::pop3client( user => $login, 
password => $password, 
host => $mailserver ); 
# Далее по тексту. 
} 
Вот в принципе и все - небольшой простенький mailreader готов.
Но есть один существенный недостаток:
"Кириллические" тексты зачастую в письме хранятся в виде mime encoded.
Поэтому чтобы их прочесть, нужно использовать соответствующие библиотеки
или писать свои конвертеры. Это уже другая тема, и в этой статье обсуждаться не будет.

PHP   Теги:

Читать IT-новости в Telegram
Информационные технологии
Мы в соцсетях ✉