Справочник функций

Ваш аккаунт

Логин:
Пароль:
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:
Убрать блок ВКонтакте навсегда

Последние темы форума

Показать новые сообщения »

Почтовая рассылка



Подписчиков: 19017
Последний выпуск: 23.04.2012

Получи, клиент, рассылку

Автор: Сергей Парижский
(www.mycomp.com.ua), №46 (425) 09.11.2006
http://heel.org.ua/

Вы, наверное, замечали: на некоторых сайтах предлагают оставить свой 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
Мне нравитсяМне не нравится

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

Код:
if (!preg_match("/(?i)^[a-z\\d_\\.-]+@[a-z\\d_\\.-]+\\.[a-z\\d_-]{2,}$/", $email))

4. choom / 24 августа 2007, 00:42:43
Мне нравитсяМне не нравится

Эту строку:
Код:
if (isset($email)) //пользователь заполнил форму подписки

Лучше вот так:
Код:
if (isset($_POST['email'])) //пользователь заполнил форму подписки


Этот регэксп не работает:
Код:
if (!preg_match("/^([a-z,._,0-9])+@([a-z,._,0-9])+(.([a-z])+)+$/", $email))

Правильно:
Код:
if (!preg_match("/(?i)^[a-z\d_\.-]+@[a-z\d_\.-]+\.[a-z\d_-]{2,}$/", $email))


Вместо этого цикла:
Код:
for($i=0;$i<$kolvo;$i++) //делаем цикл для полного перебора всех ящиков

напрашивается использование in_array()

дальше не смотрел, надоело =\
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог
Плавательные бассейны - бассейны.