Получи, клиент, рассылку
Вы, наверное, замечали: на некоторых сайтах предлагают оставить свой e-mail для того чтобы подписаться на рассылку. Вы будете получать по почте сведения о новинках сайта, и не нужно будет лезть в Интернет, чтобы посмотреть, не появилось ли там что-то новенькое. Подобный сервис мы сейчас организуем.
Проект наш будет состоять из двух сценариев и базы e-mail'ов. Один сценарий будет служить для подписки/отписки пользователей, а второй, собственно, будет осуществлять рассылку. Сначала напишем сценарий для добавления и удаления почтовых ящиков из базы. Создайте сценарий subscribe.php - для начала разработаем пользовательскую форму:
<html>
<head>
<title>
Почтовая рассылка
</title>
</head>
<body>
Подписаться на почтовую рассылку новостей сайта.<br>
Введите свой e-mail:
<form action=subscribe.php method=POST>
<input type=text size=40 maxlength=30 name=email>
<input type=submit value=Подписаться>
</form>
<p>
Если вы уже подписаны и хотите отписаться от рассылки, то есть<br> не получать больше писем с сайта, то вам необходимо заполнить поле ниже: <p>
<form action=subscribe.php method=POST> E-mail:<br><input type=text size=40 maxlength=30 name=noemail> <input type=submit value=Отписаться> </form>
Внешний вид формы показан на рис. 1. Здесь по сути две формы - для подписки на рассылку и для отказа от нее.

Далее в сценарии мы будем проверять, какую из предложенных форм заполнил пользователь. Для начала опишем условие <если пользователь решил подписаться на рассылку>:
<?php
if (isset($email)) //пользователь заполнил форму подписки
{
//проверяем введенный e-mail на корректность
if (!preg_match("/^([a-z,._,0-9])+@([a-z,._,0-9])+(.([a-z])+)+$/", $email))
//если e-mail не соответствует шаблону
{
//выводим сообщение
echo '<font color=red size=4>Неверно указан e-mail!</font>';
echo '</body></html>'; //дописываем окончание страницы
exit; //выходим
}
//иначе
$emails= file('emails.dat'); //заносим список e-mail'ов из файла в массив
$kolvo = count($emails); //определяем количество почтовых ящиков в базе
for($i=0;$i<$kolvo;$i++) //делаем цикл для полного перебора всех ящиков
//проверяем, нет ли в базе такого же e-mail'a
if (trim($emails[$i]) === trim($email))
{
echo '<font color=red size=4>Вы уже подписаны на рассылку!</font>';
echo '</body></html>';
exit;
}
$email=StripSlashes($email); //убираем все лишние символы
//открываем базу на дописывание данных
$fp = fopen('emails.dat','a+') or die('Не могу открыть файл базы рассылки!');
fwrite($fp,$email.chr(13).chr(10)); //добавляем новый e-mail в конец базы
fclose($fp); //закрываем базу
}
При попытке добавления нового почтового ящика на подписку мы делаем проверки, соответствует ли e-mail шаблону и имеется ли уже в базе такой e-mail. Теперь рассмотрим условие <если пользователь хочет отписаться от рассылки новостей>, то есть попросту дадим ему возможность удалить свой e-mail из базы:
if (isset($noemail)) //если отправлены данные формы отписки от рассылки
{
$emails= file('emails.dat'); //заносим строки базы в массив
$kolvo = count($emails); //количество строк в файле
for($i=0;$i<$kolvo;$i++) //цикл перебора всех элементов массива
//если найден e-mail, который требуется удалить
if (trim($emails[$i]) === trim($noemail))
break; //прерываем цикл
//если e-mail не был найден
if ($i == $kolvo)
{
//выводим сообщение о том, что e-mail отсутствует в базе
echo '<font color=red size=4>Вы не подписаны на рассылку!</font>';
echo '</body></html>';
exit;
}
$fp = fopen('emails.dat','w+'); //открываем файл на перезапись
for($j=0;$j<$kolvo;$j++) //цикл для перебора массива
{
/* если найден e-mail, предназначенный для удаления из базы,
итерацию цикла не производим */
if ($i==$j) continue;
fwrite($fp,$emails[$j]); //записываем e-mail'ы в базу
}
fclose($fp); //закрываем файл
}
//конец сценария
?>
</body>
</html>
Для удаления указанного почтового ящика из базы мы считываем все e-mail'ы из базы в массив. После этого методом перебора находим индекс почтового ящика, который необходимо удалить, и запоминаем его. Когда мы начинаем записывать все e-mail'ы обратно в базу, то при нахождении почтового ящика, который необходимо удалить из базы, пропускаем эту итерацию цикла и не записываем его в цикл.
Пользовательский сценарий для подписки готов, теперь создадим сценарий для себя :-) - он будет осуществлять рассылку. Для начала разработаем внешний вид формы: создайте сценарий sendmails.php и напишите в нем html-код формы:
<html>
<head>
<title>
Почтовая рассылка
</title>
</head>
<body>
<form action=sendmails.php method=post>
<b>Тема рассылки</b>: <input type=text name=subj
value="Рассылка сайта www.HeeL.net.UA" size=45><br />
<b>Текст рассылки</b>:<br />
<textarea cols=50 rows=5 name=text>Здравствуйте, хотим вас
обрадовать, что на сайте открылся форум! Будем обсуждать интересные
темы по программированию и вообще ;)
Рассылка сайта www.HeeL.net.UA </textarea>
<p>
<input type=submit value=Разослать>
</form>
На рис. 2 показан внешний вид формы. Мы вводим тему рассылки и текст, при нажатии на кнопку <Разослать> данное письмо будет рассылаться на все e-mail'ы, которые указаны в файле emails.dat.

Для обработки формы ниже напишите такой код:
<?php
$emailfile = "emails.dat";
if (!isset($text)) //если не указан текст для рассылки
{
echo "</body></html>"; //дописываем конец страницы
exit; //выходим
}
//проверяем, существует ли база и можно ли с нее считывать данные
if ((!File_Exists($emailfile)) || (!is_readable($emailfile)) )
{
echo 'Ошибка, при работе с базой '.$emailfile;
echo '</body></html>';
exit;
}
$emails = file($emailfile);
$kolvo = count($emails);
if (!isset($subj) || ($subj==='')) //если поле <Тема> не заполнено
$subj='Рассылка сайта www.HeeL.net.UA'; //пишем свою тему <по умолчанию>
//отправляем почту в цикле
for($i=0;$i<$kolvo;$i++)
/* отправляем письмо на каждый e-mail по очереди в цикле */
mail(trim($emails[$i]),trim($subj),$text);
//выводим сообщения об успешности операции
echo '<font color=red size=4><p align=center>Все письма успешно разосланы...</p></font>';
?>
</body>
</html>
Все, сценарий полностью готов, для проверки можете ввести несколько своих почтовых ящиков и попробовать осуществить рассылку.
Оставить комментарий
Оставлять комментарии могут только зарегистрированные пользователи.
Если вы не являетесь зарегистрированным пользователем, то вам необходимо зарегистрироваться. Регистрация бесплатна. Если вы уже зарегистрированы на CodeNet, то вам необходимо ввести логин и пароль в верхней (Alt-U) части страницы.
Комментарии
1. kgushin / 31 мая 2010, 11:08:39

Статья старенькая, но прокомментирую. С таким "скриптом рассылки" (вызов mail() в цикле) можно здорово нагореть. У всех хостеров дейстуют ограничения на количество отправляемых писем, и санкции за превышение часто довольно суровые (штраф или могут аблокировать как спамера). Второе -- при запуске скрипта из браузера у него ограничено время выполнения (обычно 30 секунд), и если в списке больше нескольких десятков адресов, то данный скрипт какие-то письма отправит, а остальные нет (и способа узнать, сколько отправлено, автор не предусмотрел). Невозможно узнать результат доставки письма.

В общем, данный метод рассылки в 90% случаев непригоден. Более правильное решение -- использовать сервис почтовой рассылки, предоставляющий API, например UniSender
2. NetWork / 22 февраля 2008, 19:09:04

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

[php]
$p_time = 0;
//отправляем почту в цикле
for($i=0;$i<$kolvo;$i++) {
/* отправляем письмо на каждый e-mail по очереди в цикле */
mail(trim($emails[$i]),trim($subj),$text);
//выводим сообщения об успешности операции
echo '<font color=red size=4><p align=center>Все письма успешно разосланы...</p></font>';
$p_time++;
if ($p_time == 30) {
$p_time = 0;
sleep(1);
}
}
[/php]
Если база E-mail большая то данный вариант хорошо помогает.
3. choom / 24 августа 2007, 00:46:21

блин, бэкслэши потреялись =( может быть вот так получится

4. choom / 24 августа 2007, 00:42:43

Эту строку: 

Лучше вот так:
Этот регэксп не работает:
Правильно:
Вместо этого цикла:
напрашивается использование in_array()
дальше не смотрел, надоело =\
