Глава 16. Своя рассылка на PHP

В интернете есть много бесплатных сервисов, в том числе услуги по рассылке писем подписчикам. Некоторые из них очень хороши. Однако, поскольку они бесплатны, в письмах появляется реклама. К тому же, многих не устраивают большие формы для подписки с логотипом предоставителя услуг.

Так почему бы не написать простой движок для своей рассылки и отсылать письма на свой страх и риск?

Давайте разберемся, что нам для этого потребуется. Для того чтобы посетители могли подписаться на вашу рассылку, необходима форма для ввода адреса электронной почты. Адрес нужно запомнить и сохранить в файле maillist.txt, по одному адресу на строку. После сохранения адреса, выведем соответствующее сообщение и отобразим форму для подписки следующего адреса или для его удаления. Вот, собственно, и все что нужно для начала. Остается добавить функциональность для отправки писем. Для безопасности добавим форму для ввода пароля. Затем потребуются формы для заполнения адреса отправителя, темы письма и, наконец, самого текста письма.

Форма для ввода адреса электронной почты будет состоять только из окна для ввода адреса и кнопки для подтверждения:

При обработке текста были выполнены следующие действия:

<form action="ras.php" enctype="multipart/form-data" method="post">
    <input name="email" size="30" type="text">
    <input name="submit" type="submit" value="подписаться">
</form>

Итак, в окне для ввода текста с именем email и видимой длиной в 30 символов будет вводиться адрес электронной почты. После нажатия на кнопку с надписью "подписаться", адрес будет передан скрипту ras.php для занесения в базу рассылки.

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

<?
$file = "maillist.txt"; // файл, содержащий адреса
error_reporting(0); // запрещаем вывод сообщений о возможных ошибках
function test_mail($char) // функция, проверяющая реальность адреса
{
    $flag = false;
    if (eregi("^[_\.0-9a-z-]+@([0-9a-z][-0-9a-z\.]+)\.([a-z]{2,3}$)", $char)) $flag = true;
    if ($flag) return true;
    else return false;
}
$email = trim(strtolower($email)); // получаем введенный в форму адрес с символами в нижнем регистре
function copy_mail($char) // проверяем, есть ли такой адрес в базе
{
    $file = "maillist.txt";
    $list = file($file);
    for ($i = 0; $i < sizeof($list); $i++)
        if ($char == trim($list[$i])) $flag = true;
    if ($flag) return true;
    else return false;
}
echo "<center>";
if (is_file($file)) // далее проверяем адрес вышеописанными функциями
{
    $maillist = file($file);
    if (!$email == '') {
        if (test_mail($email)) {
            if (!copy_mail($email))
            {
                $maillist[] = "\n$email";
                print "E-mail: $email добавлен базу рассылки</center>";
            }
            else print "E-mail: $email уже есть в базе</center>";
        }
        else print "E-mail: $email не существует</center>";
    }
    else print "</center>";
}
else print "Не найден файл $file ! Пожалуйста <A HREF=\"mailto:$fromemail\">сообщите</a> мне о ошибке.</center>";
echo "<br><center>Подписаться на рассылку<form method=\"post\" action=\"ras.php\" enctype=\"multipart/form-data\">";
echo "Введите mail:<input type=\"text\" name=\"email\" size=\"30\"><input type=\"submit\" name=\"submit\" value=\"подписаться\"></form></center>";
echo "<CENTER><br><br><form method=\"post\" action=\"ras.php\" enctype=\"multipart/form-data\">";
echo "Отписаться от рассылки<br>Введите mail:";
echo "<input type=\"text\" name=\"delmail\" size=\"15\"><input type=\"submit\" name=\"submit\" value=\"Отписаться\"></form></CENTER>";
$flag = false;
$fw = fopen($file, "w");
for ($i = 0; $i < sizeof($maillist); $i++)
    if (trim(strtolower($delmail)) == trim(strtolower($maillist[$i]))) {
        if (!$delmail == '')
        {
            print "<center>$delmail удален из базы рассылки</center>";
            $flag = true;
        }
    }
    else fputs($fw, $maillist[$i]);
fclose($fw);
if (!$delmail == '')
    if (!$flag) print "<center>$delmail не найден в базе рассылки</center>";
?>

Вот наш код сохранения и удаления адресов готов. Теперь надо позаботиться о средствах отправки почты. Не будем же мы через Outlook отсылать? Как уже говорилось, защитим возможность отправки паролем, который будем вводить на специальной форме:

<form method="POST" action="out.php">
    <input type="password" name="pass" value="">
    <input type="submit" value="войти">
</form>

Поле для ввода с именем pass будет служить для ввода пароля. После нажатия на кнопку с надписью войти, пароль будет передан скрипту out.php:

$subject = "Рассылка моего сайта"; // тема рассылки
$fromemail = "мое@мыло"; // ваш адрес (для ответов)
$file = "maillist.txt"; // список адресов подписчиков
$password = "secretpassword"; // ваш пароль для рассылки

if ($pass == $password) // если пароль ввели правильный
{
    echo "<form method='POST' action='send.php'>";
    echo "адрес отправителя<br><input type='text' name='fromemail' value='$fromemail' size='25'><br>";
    echo "тема письма<br><input type='text' name='subject' value='$subject' size='50'>";
    echo "<br>текст письма:<br><textarea name='body' rows='8' cols='50'></textarea>";
    echo "<br><input type='submit' value='Отправить сообщение'></form>";
}

Осталось рассмотреть только один скрипт - тот самый, который будет отсылать почту:

<?
error_reporting(0);
$odr = "\n\n\n Для отказа от подписки воспользуйтесь ссылкой\n";
$homepage = "http://адрес.сайта/ras.php";
$subject = $HTTP_POST_VARS["subject"];
$body = $HTTP_POST_VARS["body"];
$subject = stripslashes($subject);
$body = stripslashes($body);
$file = "maillist.txt";
$maillist = file($file);
print "В базе " . sizeof($maillist) . " адресов<br>";
for ($i = 0; $i < sizeof($maillist); $i++) {
    mail($maillist[$i], $subject, $body . "$odr $homepage?delmail=$maillist[$i]", "From: $fromemail");
}
echo "Готово!";
?>

Тут все просто: получаем значения, введенные в предыдущую форму и в цикле отправляем их по очереди на каждый из адресов.

Вот совсем и несложно! Теперь вы имеете мощный инструмент по ведению полностью собственной рассылки. Нет больше для вас никаких правил. Что хотите, то и пишите в своей рассылке. Полная свобода по конфигурации и внешнему виду форм для подписки.

Разумеется, данный код является лишь минимальным набором. Например, с помощью функции mail() можно организовать себе извещение о новом подписчике, а подписчику об удачной регистрации, рассказать побольше о рассылке.

Разумеется, говоря о полной свободе, я ни в коем случае не имел в виду принудительную подписку или, проще говоря, спам. Если вдруг кто решит рассылать спам таким образом, то пусть учтет, что на него сразу начнут жаловаться администрации хостинга. И неважно, платный хостинг или нет, если администрация хостинга заметит подобные действия, она анулирует предоставление своих услуг вам без возмещения убытков. А с халявными хостингами еще туже. Во-первых, надо просить персональное разрешение у администрации на открытие данной функции, во-вторых, как правило, стоит лимит в 1 письмо за минуту. Так что господа спамеры, обламайтесь :)

На такой вот веселой ноте и закончим.