Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Экзамен / web / example1 / Введение в PHP.doc
Скачиваний:
101
Добавлен:
18.05.2015
Размер:
3 Mб
Скачать

Автоответчик

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

autoresponder.php:

<html><head><title>Настройка автоответчика</title></head><body>

<form method=post action="writeautoresponder.php">

<br>

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

<br><br>

<textarea cols=70 rows=20 name="Body">

<? readfile("data/autoresponder.txt"); ?>

</textarea>

<br><br>

<input type="submit" name="submit" value="Сохранить изменения"></FORM>

<br>

</body></html>

Во-вторых, пишем скрипт, сохраняющий в соответствующем файле (autoresponder.txt) произведенные администратором изменения.

writeautoresponder.php

<html><head><title>Сохраняем изменения...</title></head><body>

<br><br>

<b>Сохранено следующее сообщение, использующееся автоответчиком:</b><br>

<?

$myfile = fopen("data/autoresponder.txt","w");

fputs($myfile,$Body);

fclose($myfile);

?>

<br>

<pre><? echo $Body ?> </pre><br>

<br>

<a href="index.php">На главную</a>

Теперь следует обеспечить возможность подписки посетителей к списку рассылки. Для этого создадим HTML-файл примерно со следующим содержанием:

<b>Получать новости сервера для администраторов на e-mail:</b><br>

<form method="post" action="thanks.php">

<input type="text" name="Email" size="20">

<input type="hidden" name="List" value="admins.txt">

<input type="submit" Value="Подписаться"></form>

Результат обращения к этому файлу из окна броузера представлен на рис. 4. Последним на сегодня будет скрипт помещения нового e-mail-адреса в соответствующий лист рассылки. В нашем случае файл листа имеет имя "admins.txt" (обратите внимание на скрытый параметр List). Код скрипта thanks.php приводится ниже:

<html><head><title>Спасибо!</title></head><body>

<?

$Body = readfile("data/autoresponder.txt");

mail("$Email","Подписка на рассылку", "$Body","From: Me\nReply-To: me@myaddress.com");

$myfile = file("data/admins.lst");

$fh = fopen("data/admins.lst","w");

for ($index=0; $index < count($myfile); $index++)

{

if ($Email != chop($myfile[$index]))

{fputs($fh,$myfile[$index]);}

}

fputs($fh,$Email."\n");

fclose($fh);

?>

Спасибо за то, что подписались на нашу рассылку!

<br><br>

</body></html>

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

Почтовые функции в рнр

Одним из возможных применений imap функций является создание почтового демона, который будет управлять подпиской и отпиской пользователей от вашей почтовой рассылки. Для реализации этой задачи, обычно в рассылках используются два метода. Первый предполагает, что пользователь должен зайти на некую страницу и подтвердить свои действия, второй требует отправки письма. Второй так же требует, чтобы скрипт-обработчик регулярно запускался cron daemon?om. Из-за этого он не настолько популярен как первый способ.

Но, как можно заметить, наиболее серьезные рассылки используют второй способ. Поэтому, если у вас есть возможность использования crond, воспользуйтесь им.

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

Алгоритм работы самого скрипта придумать несложно. Демон устанавливает соединение с почтовым сервером, и проверяет наличие на нем писем. В случае если писем нет, работа скрипта прекращается.

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

Закончив разбор всех писем, он очищает ящик.

Не буду утомлять читателя блок-схемами, так что сразу перейдем к делу. Для открытия ящика используется функция imap_open. Поскольку РНР поддерживает работу с несколькими протоколами, то необходимо явно указать, какой протокол используется для работы с ящиком. В нашем случае это POP3 на 110 порту (стандарт). Присваиваем результат выполнения скрипта переменной $my_box.

$my_box = imap_open("{you.pop.host/pop3:110}", "login", "password");

В дальнейшем вы увидите, что эта переменная будет использоваться пратически во всех imap функциях. Далее проверяем ящик на наличие писем. Проверку выполняет функция imap_num_msg.

$n = imap_num_msg($my_box);

В результате переменная $n будет содержать количество писем в ящике. Число это может быть или больше нуля, или равно ему (если ящик пуст).

Если письма есть, то в цикле while выполняем разбор писем, последовательно увеличивая номер письма на единицу. Обратите внимание, что первое письмо в ящике будет иметь номер 0, как, и первый элемент массива.

Для увеличения номера письма, присваиваем переменной $m значение 0, а потом в условиях выполнения цикла увеличиваем ее на единицу $m++.

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

Imap_header возвращает в результате выполнения объект, содержащий исчерпывающую информацию о заголовке письма. Среди всего прочего, этот объект содержит массив from, в котором содержаться четыре значения. Это personal, adl, mailbox и host. Нас из них интересуют только mailbox и host. Подставляя их, мы получим адрес, с которого было отправлено письмо.

$h = imap_header($my_box, $m);

$h = $h->from;

:

foreach ($h as $k => $v) {

$mailbox = $v->mailbox;

$host = $v->host;

$personal = $v->personal;

$email = $mailbox . <@> . $host;

imap_fetch_overview - позволит нам узнать тему письма. Для этих же целей можно было бы использовать и imap_header но по ряду причин это, иногда может не сработать. Из массива, который возвращает эта функция, нам нужно только поле subject

$s = imap_fetch_overview($my_box, $m);

foreach ($s as $k => $v) {

$subj = $v->subject;

}

Дальнейшие наши действия сводятся к тому, чтобы вытащить email из базы, и в случае наличия его там, пометить всю строку с этой записью как <проверенную>, либо удалить. Предположим, что после заполнения формы рассылки на сайте, подписчику присваивается статус 0, а после подтверждения подписки он меняется на 1.

if ($subj == "SUBSCRIBE") {

mysql_query("UPDATE subscribe SET stat=1 WHERE email=$my_email");

$del = imap_delete($my_box, $m);

mail($email, $add_sbj, $add_text, $headers);

}

elseif ($subj == "UNSUBSCRIBE") {

mysql_query("DELETE FROM subscribe WHERE email = $my_email");

$del = imap_delete($my_box, $m);

mail($email, $del_sbj, $del_text, $headers);

}

else {

$del = imap_delete($my_box, $m);

mail($email, $err_sbj, $err_text, $headers);

}

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

$clear = imap_expunge($my_box);

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

Листинг всей программы за исключением параметров соединения с базой (db.php):

<?

include "db.php";

$my_box = imap_open("{you.pop.host/pop3:110}", "login", "password");

$n = imap_num_msg($my_box);

$m = 0;

$add_text = "

Спасибо за подтверждение вашей подписки ";

$add_sbj = "You added!";

$del_text = "

Вы были удалены из списка рассылки. ";

$del_sbj = "Delete from list";

$err_text = "

Извините но этот почтовый ящик используется

только для администрирования рассылки";

$err_sbj = "Error";

$headers = "From: Subscribe Robot <You@mail.box>

X-mailer: PHP4

Content-type: text/plain; charset=windows-1251

";

if($n != 0) {

while($m++ < $n) {

$h = imap_header($my_box, $m);

$s = imap_fetch_overview($my_box, $m);

$h = $h->from;

foreach ($h as $k =>$v) {

$mailbox = $v->mailbox;

$host = $v->host;

$personal = $v->personal;

$email = $mailbox . "@" . $host;

$my_email = mysql_escape_string($email);

}

foreach ($s as $k =>$v) {

$subj = $v->subject;

}

if ($subj == "SUBSCRIBE") {

mysql_query("UPDATE table SET stat=1 WHERE email=$my_email");

//print mysql_error();

$del = imap_delete($my_box, $m);

mail($email, $add_sbj, $add_text, $headers);

}

elseif ($subj == "UNSUBSCRIBE") {

mysql_query("DELETE FROM table WHERE email = $my_email");

$del = imap_delete($my_box, $m);

mail($email, $del_sbj, $del_text, $headers);

}

else {

$del = imap_delete($open_box, $m);

mail($email, $err_sbj, $err_text, $headers);

}

}

$clear = imap_expunge($my_box);

}

?>

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

Соседние файлы в папке example1