Простой скрипт email рассылки

рассылка писем

Не так давно понадобилось написать небольшой скрипт для собcтвенных нужд. О нём сегодня мы и поговорим. Язык программирования — PHP. Приступим.

Постановка задачи и выбор методов её решения

Задача: написать максимально быстро и просто скрипт для отправки e-mail сообщения на n-ное количество адресов. Дело в том, что иногда нужно послать письмо нескольким адресатам, но так, чтобы они друг о друге не знали. То есть, исключаем тупое копирование всех адресов через запятую в поле «Кому».

Скачать исходный код себе на компьютер!

Язык программирования — PHP.

Приступим.

Почему PHP? Да потому что на PHP это сделать очень просто и он стоит на любом хостинге (платном конечно). Тем более, скрипт не нужно хранить на компьютере, а лучше залить на сервер и пользоваться откуда угодно. Даже с мобильника.

Если говорить более простым языком, мы пишем небольшой скрипт e-mail рассылки. Сразу же в голове рождается представление работы скрипта.

У нас есть форма с полями:

Кому (список получателей)

Тема сообщения

Текст сообщения

Адрес отправителя (выбор из перечня)

Схема работы: Вводим данные и нажимаем «Отправить» → происходит отправка писем → получаем отчёт.

Есть также пару особенностей. Для отправки писем желательно использовать небольшой тайм-аут, чтобы наш сервер не посчитали спаммером. Отчёт желательно записать в небольшой текстовый файл. Нужно защитить скрипт от несанкционированного использования.

Пишем скрипт

Здесь я не буду описывать процесс написания, а просто приведу максимально откомментированный код.

<?php
  // Устанавливает лимит времени исполнения для этого файла (связано с тайм-аутом)
	set_time_limit (1200);
  // Адреса отправителя
	$mail1="Ваше имя 1 <your1@email.com>";
	$mail1="Ваше имя 2 <your2@email.com>";
	$mail1="Ваше имя 3 <your3@email.com>";

  // Обрабатываем адреса для отображения в форме
	$tmail1=htmlspecialchars($mail1);
	$tmail2=htmlspecialchars($mail2);
	$tmail3=htmlspecialchars($mail3);
	
  // Далее идёт сам скрипт
  // Если массив POST не пустой, отправка состоялась
	if (!empty($_POST) && !isset($sent)) {
  
// Определяем переменные
	$emailer_subj = $_POST['emailer_subj'];
	$emailer_mails = $_POST['emailer_mails'];
	$emailer_text = $_POST['emailer_text'];
	$emailer_yourmail = $_POST['emailer_yourmail'];

    // Теперь проверяем заполнение всех полей
	if (empty($emailer_subj) || $emailer_subj=="Тема письма") {
    // Если тема пустая...
    $mail_msg='<b>Вы не ввели тему письма</b>';
  } elseif (empty($emailer_mails) || $emailer_mails=="Почтовые адрсе") {
    // Если адресов нет...
    $mail_msg='<b>Не указано адреса получателей</b>';
  } elseif (empty($emailer_text) || $emailer_text=="Текст письма") {
    // Если сообщение пустое...
    $mail_msg='<b>Вы не ввели текст письма</b>';
  } else { // Если все поля заполнены верно...
    // Готовим сообщение об успешной отправке... Вдруг у вас какой-то необычный браузер
    $mail_msg='Ваше сообщение отправлено.<br>Нажмите <a href="'.$_SERVER['REQUEST_URI'].'">здесь</a>, если ваш браузер не поддерживает перенаправление.';
    // Готовим заголовки письма... Будем отправлять письма в формате HTML и кодировке UTF-8
    $headers="MIME-Version: 1.0\r\n";
    $headers.="Content-type: text/html; charset=utf-8\r\n";
    $headers.="From: $emailer_yourmail";
	
	// Обработка письма. Нужно удалить лишние пробелы и проставить переносы.
	$emailer_text=preg_replace("/ +/"," ",$emailer_text); // множественные пробелы заменяются на одинарные
	$emailer_text=preg_replace("/(\r\n){3,}/","\r\n\r\n",$emailer_text); // убираем лишние переносы (больше 1 строки)
	$emailer_text=str_replace("\r\n","<br>",$emailer_text); // ставим переносы
	
	// Получаем массив адресов. В качестве разделителя у нас используется запятая.
	$emails=explode(",", $emailer_mails);
	$count_emails = count($emails); // Подсчёт количества адресов
	// Запускаем цикл отправки сообщений
    for ($i=0; $i<=$count_emails-1; $i++) // Отчёт начинается в массиве с нуля, поэтому уменьшаем сумму на единицу
    {
    // Подставляем адреса получаетелей и обрезаем пробелы с обоих сторон, если таковые имеются
    $email=trim($emails[$i]);
    // Отправляем письмо и готовим отчёт по отправке
	if($emails[$i]!="") { // Проверка на случай попадения в массив пустого значения
    if(mail($email,$emailer_subj,$emailer_text,$headers)) $report.="<li><span style=\"color:green;\">Отправлено: ".$emails[$i]."</span></li>"; else $report.="<li><span style=\"color:red;\">Не отправлено: ".$emails[$i]."<span></li>";
	sleep(5); // Делаем тайм-аут в 5 секунд
	}
    }
	
	// Запись отчёта в файл. Файл будет сгенерирован в той же папке, под названием log.txt. Проверьте настройку прав папки.
	$log=fopen("log.txt","w");
	fwrite($log,$report);
	fclose($log);
    // Переменная $sent – признак успешной отправки
    $sent=1;
  }
} else { // Если в массиве POST пусто, форма еще не передавалась
  // Готовим приглашение
  $mail_msg='Все поля обязательны для заполнения.';
  // Поля темы, адресов получаетелей и получателей, и текста в этом случае должны быть пустыми
  $emailer_text=$emailer_subj=$emailer_mails=$emailer_yourmail='';
}

  // Если $sent не существует, выводим форму или отчёт
	if (!isset($sent)) {
  // Если сообщение уже отправлено - выводим отчёт
    if(isset($_GET['messent']))
	{echo $text.="<b style=\"text-align:center;margin-top:200px;display:block;\">Всё окей. Сообщение отправлено. <a href=\"emailer.php\">Ещё?</a><br><br><u>Отчёт:</u></b> <ol style=\"display:block;width:300px;margin:10px auto;\">";
	readfile("log.txt");
	echo"</ol>";}
	else {
  // Или выводим форму, если сообщение ещё не отправлено
    echo $text.=<<<post
    <script type="text/javascript">
    function form_validator(form) {
    if (form.emailer_subj.value=='' || form.emailer_subj.value=='Тема письма') { alert('Укажите тему письма.'); form.emailer_subj.focus(); return false; }
    if (form.emailer_mails.value=='' || form.emailer_mails.value=='Почтовые адреса') { alert('Укажите адреса получаталей.'); form.emailer_mails.focus(); return false; }
    if (form.emailer_text.value=='' || form.emailer_text.value=='Текст письма') { alert('Вы не заполнили поле сообщения.'); form.emailer_text.focus(); return false; }
    return true;
    }
    </script>
	<style type="text/css">
	form {display:block;margin:20px auto;width:500px;}
	textarea, input, select {width:100%; margin:5px 0;}
	textarea {height:200px;}
	.red {color:#a00;}
	</style>
    <form method="post" onsubmit="return form_validator(this);">
	<p class="red">$mail_msg</p>
	<input type="text" name="emailer_subj" id="emailer_subj" value="Тема письма" title="По какому поводу пишем?" onfocus="if (this.value=='Тема письма') this.value='';" onblur="if (this.value=='') this.value='Тема письма';">
	<textarea name="emailer_mails" id="emailer_mails" title="Кто получатели?" onfocus="if (this.value=='Почтовые адреса') this.value='';" onblur="if (this.value=='') this.value='Почтовые адреса';">Почтовые адреса</textarea>
	<textarea name="emailer_text" id="emailer_text" title="Что пишем?" onfocus="if (this.value=='Текст письма') this.value='';" onblur="if (this.value=='') this.value='Текст письма';">Текст письма</textarea>
	<select name="emailer_yourmail">
	<option value="$mail1">$tmail1</option>
	<option value="$mail2">$tmail2</option>
	<option value="$mail3">$tmail3</option>
	</select>
	<input type="submit" value="Отправить" title="Отправить мыл">
	</form>
post;
}
}
else { // А если существует...
  // Посылаем в заголовке редирект (303 Refresh) на этот же адрес с дополнительным параметром messent
  $ret_uri=$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
  header("Refresh: 0; URL=http://".$ret_uri."?messent");
  exit;
}

?>

Защита скрипта

Создайте папку, где будет находиться скрипт, и положите туда файл .htaccess, с таким содержанием. Эти пару строк ограничат доступ по IP адресу.

Order Deny,Allow
Deny from all
Allow from ваш IP

Или, если у вас не постоянный IP адрес, можно добавить пароль.

if (!isset($_SERVER['PHP_AUTH_USER'])) {
// посылаем браузеру запрос логина/пароля
header("WWW-Authenticate: Basic realm=\"Enter login and password\"");
header("HTTP/1.0 401 Unauthorized");
exit;
} else {
if($_SERVER['PHP_AUTH_USER']!=='Ваш логин' && $_SERVER['PHP_AUTH_PW']!=='Ваш пароль')
{
header("WWW-Authenticate: Basic realm=\"Enter login and password\"");
header("HTTP/1.0 401 Unauthorized");
exit('Введён неверный логин или пароль');
}
else {
//Сюда нужно вставить тело скрипта
}

Доработка скрипта

Конечно, можно бесконечно дорабатывать этот скрипт, ведь решение написано «на коленке», однако свою функцию он выполняет. Неоднократно пользовался им и сбоев не было.

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

Можно вставить себя последним в списке, чтобы проконтролировать отправку. Вдруг что с файлом случится :)

Надеюсь, эта статья поможет вам в освоении языка программирования PHP.

Автор: Алексей Опанасенко

Редакция: Рог Виктор и Андрей Бернацкий. Команда webformyself.

E-mail: contact@webformyself.com

Проект webformyself.com — Как создать свой сайт. Основы самостоятельного сайтостроения

P.S. Хотите опубликовать интересный тематический материал и заработать? Если ответ «Да», то жмите сюда.

Курс по программированию на языке PHP

Изучите PHP с нуля до результата!

Смотреть курс

Метки: , ,

Комментарии Вконтакте:

Комментарии Facebook:

Комментарии (28)

  1. Елена

    Здравствуйте, Андрей и Виктор! Материал замечательный и очень актуальный. Обязательно попробую, но только не сегодня. Мои дипломники вышли на финишную прямую — идет работа над ошибками, удовлетворение капизов руководителей дипломов, подготовка докладов, рецензий, аннотаций и т.д. и т.п.Передайте, пожалуйста, мой восторг автору — Алексею Опанасенко.С уважением, Елена Владиславовна, kiselevaev2009@mail.ru

  2. Василий

    Очень нужный скрипт-однако!Ещё бы прояснили «чайнику»-подробнее-как пользоваться им( можно -ли загружать этот код хостеру или это только пример;в какую папку на хостинге заливать и как отправлять им письма?)Спасибо!

  3. Dan

    И правда,напишите куда вставлять

    • RohViktor

      Все очень просто.

      1. Делаем файл к примеру emailer.php, где кодом будет весь код из данной статьи.

      2. Закачиваем на свой хостинг в папку www/

      3. потом пшем в строке браузера доменное_имя.ru/emailer.php и пользуемся.

      Вот и все. Главное залить на сервер!

      • Never Lex

        Спасибо, Виктор, за ответ.

        Я бы хотел уточнить, что данный скрипт интересен в первую очередь, как пример людям, которые изучают PHP. Вы можете дорабатывать и изменять это скрипт как угодно.

        • Женя

          А возможно ли с вами сотрудничать (я занимаюсь тем что продаю рабочие скрипти ) если да то напишите мне на почту буду рад сотрудничать

  4. Алексей

    Интересно — даже не предполагал о такой возможности

  5. Slava

    А у меня сервер не разрешает выполнение скрипта. Что делать?

  6. Менеджер

    Замечательная новость. Очень признательна автору сайта за четкое изложение материала! Спасибо!!!

  7. Константин

    Скрипт, приведенный в статье, в основном годится качестве учебного примера. Его можно безбоязненно использовать для отправки максимум одного-двух десятков сообщений. Если хотите отправлять больше, то обязательно нужно заранее спросить у хостера, на чьем сервере будет размещен скрипт, какие ограничения накладываются на отправку писем. Обычно на shared хостингах пользователю разрешается посылать не больше нескольких сотен или даже десятков писем в день, бывают и более строгие ограничения (напр., на отправку в течение часа).

    Еще один базовый недостаток скрипта: значение, возвращаемое функцией mail(), позволяет узнать, было ли письмо поставлено в очередь на отправку или нет. Невозможно узнать не только было ли оно доставлено (а если нет, то почему), но даже предпринимались ли вообще попытки доставки. Чтобы получить эту информацию, нужно непосредственно взаимодействовать с SMTP-сервером. Это обычно делается с помощью готовых библиотек, например PEAR::Net_SMTP. В этом случае можно получить идентификатор сообщения, а затем, анализируя логи сервера и письма, приходящие на адрес, указанный в хедере Return-path, определить результат его доставки.

    В общем, советую самостоятельно автоматизацией рассылки не заниматься, а воспользоваться одним из сервисов рассылки, благо в Рунете их немало. Например, система почтовой рассылки UniSender позволяет не только узнать результат доставки письма, но и отследить прочтение и переход по ссылкам в письме.

    • Vlad

      Дело в том, что на UniSender нужно подтверждать почтовые адреса — что это не спам!!! Кто знает сервисы рассылки — где можно загружать любые почтовые адреса без ограничений???

  8. Never Lex

    Константин, конечно. По учебность примера писалось и в само статье :) Но отправлять несколько писем тоже можно.

  9. Сергей

    Добрый день!
    Спасибо скрипт отличный!
    Но подскажите что изменить что-бы в приходящем письме не отображался весь список е-mail адресов ( в поле кому в полученном письме)

    • Never Lex

      Вы уверены, что пользовались скриптом, указанным в статье?
      Этот скрипт как раз решает данную проблему. В поле «кому» должен быть только 1 адрес. Или может вы не разделяете адреса запятой? Тогда вообще не понятно как письмо приходит.

  10. Сергей

    Да спасибо! заработало!

  11. Игорь

    Отличный скрипт! Еслибы еще кто нибудь подсказал хостинг на котором можно его разместить, а то хостеры сразу блокируют аккаунт ((, Подскажите кто нибудь такой безотказный хостинг, буду примного благодарен!!! Заранее всем спасибо!

  12. Олег

    Обрабатываем адреса для отображения в форме
    010. $tmail1=htmlspecialchars($mail1);
    011. $tmail2=htmlspecialchars($mail2);
    012. $tmail3=htmlspecialchars($mail3); Не пойму, что сюда нужно поставить(Е-мейл, адрес сайтаЮ страницы) все время выдает ошибку:
    Parse error: syntax error, unexpected ‘:’ in /home/krim124/data/www/evpatoria-kurort.com.ua/cod/emailer.php on line 9

    • Andrey Bernacki

      Так у вас ругается на 9-ую строку. А не на 10, 11, или 12 как вы показали. Причем ругается на символ «:» . Проверьте 9-ую строку еще разок. Если что, такие вопросы на e-mail.

  13. max

    Всё Ок работает, но:

    1. Та часть кода, где устанавливается таймаут, либо там ошибка, либо у меня на хостинге ограничения. Просто убрал эту часть кода.

    2. Когда пишешь текст сообщения на русском языке, на мыло отправителя приходят кракозябры, писать нужно на ангельском или транслите, тогда всё ОК. Как писать на русском?

  14. max

    По второму вопросу всё решил, поменял кодировку.
    Также переписал код, что бы не выбирать адреса отправителей со списка, а вписываем какой желаем)
    Отличный код для знакомства и экспериментов с PHP)

    • Шахин

      «Также переписал код, что бы не выбирать адреса отправителей со списка, а вписываем какой желаем» интересный вариант. не подскажите как это сделали? в смысле какой код написали

  15. Виталий

    Очень бы хотелось увидеть пример с возможность прикрепить файлы. Был бы очень благодарен

  16. Gawrilowalex

    Привет, спасибо за скрипт искал давно уже. Но вот у меня проблема кодировка в сообщение выходит в виде ??????

  17. Роман

    Хорошая статья. Но для качественных Email рассылок все же лучше пользоваться качественным софтом или сервисами. Т.к. они предназначены именно для этих целей. Сами на работе пользуемся Newsletter Plus Software. Достаточно простой и быстрый скрипт, и к тому же с современным responsive дизайном.

  18. Николай

    Зачем там усложнять себе жизнь, если можно приобрести программу для e-mail рассылки StandartMailer. Программа расчитана на выполнение сложных задач по обходу спам фильтров и прочих подводных камней. Очень хорошая программа. Сам пользуюсь и вам советую.

    • Андрей Кудлай

      Николай, здесь есть несколько вариантов ответа на Ваш вопрос зачем:
      1. А если кто-то не хочет/не может приобрести эту программу?
      2. А если необходимо клиенту сделать сайт с возможностью рассылки по базе клиентов? Мы ведь не будем говорить клиенту, что такой функционал делать не будем, а вместо это предложим клиенту купить дополнительно к сайту программу. Я бы на месте клиента обиделся на подобное предложение, поскольку не хочу приобретать дополнительно программу, а хочу волшебную кнопку на сайте, кликнув по которой по базе клиентов сайта будет производиться рассылка.

  19. Андрей

    Как по мне, так скрипты это уже прошлый век! Легче просто зайти на сервис рассылок и сделать всё за пару кликов, не напрягаясь.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Я не робот.

Spam Protection by WP-SpamFree