Скрипт отправки почты на PHP

Оглавление:

Введение. Значение почтовых писем

Без почты никуда. Именно по почте мы получаем «волшебные» письма подтверждения на сервисах различных родов и мастей. Именно на почту приходят письма «обратной связи». Практически ни одно веб-приложение или веб-сайт ни обходятся без отправки почты. Поэтому, можно сказать, что отправка почты на php является актуальной проблемой среди программистов и разработчиков. PHP отправка почты не случайна, ведь практически все динамические сайты используют этот язык программирования. В этой статье я постараюсь объяснить, как написать правильный скрипт отправки почты на php, минуя частые ошибки программирования в этой стезе.

Формат сообщения

Как и везде сейчас, в почтовых письмах тоже есть свои стандарты (форматы). Перед конструированием формы отправки необходимо ознакомиться с документами, освещающими стандарты отправки почты:

  • Основной документ оправки на английском языке — RFC 822 
  • Документ, описывающий расширения — RFC 2045

Приведу пример готового к отправке сообщения, написанного в соответствии с обговоренными стандартами:

From: =?windows-1251?b?0J7RgtC/0YDQsNCy0LjRgtC10LvRjD89?= <[email protected]>
To:  =?windows-1251?b?0J/QvtC70YPRh9Cw0YLQtdC70Yw/PQ==?= <[email protected]>
Subject: =?windows-1251?b?0Y3RgtC+INGC0LXQvNCwINGB0L7QvtCx0YnQtdC90LjRjz89?=
Content-Type: text/plain; charset="windows-1251"
Content-Transfer-Encoding: 8bit

Это сообщение содержит одну строку и написано на русском языке.

Популярные и всем известные почтовые клиенты (MS Outlook, например) используют именно такой формат для отправления сообщений. К слову, многие из клиентов предоставляют исходный код формата сообщений. Именно такого формата нам необходимо добиться для отправки почты на php.

Электронное письмо содержит две части: в верхней части размещаются заголовки, а в нижней — текст письма. Пустая строка разделяет эти части. Заголовки состоят из строк, в которых содержится тема письма (Subject), имя и адрес отправителя (From), получателя (To) и другая информация. В самом простом случае каждая строка содержит пару «ИмяЗаголовка: ЗначениеЗаголовка». Особенно необходимо подчеркнуть, что, согласно стандартам, в заголовках ни при каких обстоятельствах не должны содержаться русские символы.

Читайте также:  Делаем редирект на PHP разными способами

Использование русских символов в заголовках

Так как русские символы недопустимы в заголовках, их необходимо закодировать. Стандарты, о которых мы уже упоминали, описывают способ кодирования «запрещенных» символов. Общий формат выглядит так:

=?кодировка?способ кодирования?закодированный текст?=

Кодировка может быть любой из списка «windows-1251», «koi8-r», «utf-8» и т.д. Как правило, кодировка будет совпадать с той, в которой работает сайт. Таким образом, в большинстве случаев это будет «windows-1251» или «utf-8».
Способ кодирования указывает на то, каким именно образом русские символы будут преобразованы в безопасный набор. Способа определяется два: «Q-encoding» (обозначается одной буквой «Q») и «Base64» (обозначается одной буквой «B»).
К сожалению, функции, которая могла бы обычную строку преобразовать в Q-encoded текст, в PHP нет, зато есть функция, которая умеет выполнять аналогичное преобразование в Base64. Итак, PHP код правильного создания заголовка темы почтового сообщения может выглядеть следующим образом:

$subject = "=?windows-1251?b?" . base64_encode($_POST["subject"]) . "?=";

Здесь предполагается, что в переменной $_POST[«subject»] у Вас содержится тема почтового сообщения, записанная по-русски в кодировке windows-1251.
Адрес отправителя или получателя может быть записан в виде «[email protected]» или в виде «Имя пользователя [email protected]». Во втором случае имя пользователя необходимо преобразовать, как в предыдущем примере. Ниже приведен пример, где в переменной $_POST[«username»] содержится имя пользователя, а в переменной $_POST[«email»] — его электронный адрес:

$sender = "=?windows-1251?B?" . base64_encode($_POST["username"]) . "?= <" . $_POST["email"] . ">";

Функция mail()

Отправка почтовых сообщений в большинстве скриптов выполняется системной функцией mail(). Описание синтаксиса функции mail всегда можно найти в оригинальном руководстве php. Эта функция принимает всего 5 параметров, из которых первые три являются обязательными, а последние два — опциональными:

  • to — Электронный адрес получателя сообщения
  • subject — Тема сообщения
  • message — Тело сообщения
  • additional_headers — дополнительные заголовки
  • additional_parameters — дополнительные параметры

На самом деле функция mail() просто формирует строку следующего вида:

$additional_headers
To: $to
Subject: $subject

$message

Затем передает ее на обработку стандартной UNIX-команде отправки почты, которая носит имя /usr/sbin/sendmail. Сравнивая то, что выдает mail(), с тем, что должно получиться (см. пример выше), можно составить точный план подготовки переменных для передачи в функцию:

  1. Закодировать поле Subject с использованием base64, как в примере выше.
  2. Закодировать поле To.
  3. В случае необходимости создать $additional_headers, самостоятельно сформировав все необходимые заголовки (например, добавив поле «From:») и разделив эти заголовки парой символов «\r\n».

После этого сформированный набор параметров можно передавать на вход функции mail().

Работа над ошибками с помощью additional_parameters

Как уже упоминалось выше, функция mail() для отправки почты просто вызывает стандартную команду sendmail, при необходимости передавая ей дополнительные параметры. В каком случае может возникнуть необходимость их использования? Самый часто встречающийся случай — проблема с адресом отправителя. Этот адрес нередко изменяется функцией sendmail на адрес вида «имя_пользователя_на_сервере_хостинга@адрес_сервера_хостинга.ru». Чтобы избежать такого поведения, необходимо передать команде параметр «-femail@отправителя.ru» (обратите внимание на формат строки: «минус-эф», а затем без пробелов электронный адрес).

Защита от спама

Спамеры очень часто для рассылки используют плохо написанные формы отправки почты на PHP. Дело в том, что стандарт допускает использование нескольких получателей, которые могут быть перечислены через запятую в заголовке «To», а также использование произвольного количества специальных заголовков с именем «Сс» (копия) и «Bcc» (скрытая копия). Предположим, что в Вашей форме есть поле темы, которое без изменений транслируется в заголовок «Subject». Для того чтобы отправить произвольное сообщение на тысячу адресов, спамеру достаточно в поле Subject вписать примерно такой текст:

Hello
Cc: [email protected]
Cc: [email protected]
...
Cc: [email protected]

Таким образом отправляемое письмо будет дополнено заголовками «Cc» и почтовая программа, обнаружив все эти заголовки в тексте письма, примется рассылать его всем получателям из списка. Аналогичная ситуация и с переменными $additional_headers и $to — любое из них при удачном стечении обстоятельств может быть использовано злоумышленниками в своих интересах.
Борьба с этим явлением может вестись двумя способами:

  1. Проверка всего пользовательского ввода и фильтрация опасных символов (т.е символов «\r» и «\n»). Эти символы нужно либо заменять на пробелы, либо отказываться обрабатывать некорректно введенные параметры. Например, замену можно выполнить так:
    $from = preg_replace("/[\r\n]/", " ", $_POST["sender"]);
  2. Выполнение кодирования Base64, помимо прочего, защищает и от спамеров, т.к. «вытягивает» закодированный текст в одну строку.

Отправка почты PHP просто

Существует два варианта упрощения жизни при работе с формой отправки почты.

  1. Использование готовых решений для отправки почты. В качестве примера можно привести класс PHPMailer, который легко позволяет реализовать все возможности, описанные выше, и еще целый ряд того, о чем не было упомянуто.
  2. Использование конструктора сайтов. Более подробную информацию о конструкторе можно найти по ссылке. Если говорить коротко, то конструктор позволяет без особого труда создать простой сайт, в который, в числе прочего, будет включена грамотная реализация формы отправки сообщений.
Рейтинг
( Пока оценок нет )
Блог о программировании, продвижении и дизайне.
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: