Как сделать отправку письма на почту php

Обновлено: 04.07.2024

Стандартное электронное письмо – это обычный текст, что и используется большинством разработчиков, поэтому создание MIME заголовков для HTML писем может стать сложным процессом. Теперь трудности вам не грозят, потомучто у вас есть чудесная библиотека PHPMailer, которая, к тому же, бесплатна.

В этом обучающем курсе мы будем подробно обсуждать особенности и возможности этой библиотеки.

Требования

Требования у данной библиотеки очень скромны. Вам нужен только PHP и возможность отсылать письма посредствам команды mail() или через SMTP соединение.

Также вы должны понимать основы объектно-ориентированного программирования (ООП), или, по крайней мере, понимать как правильно применять данные ниже примеры.

Не переживайте! Этот курс достаточно прост!

О PHPMailer

Что может PHPMailer

На момент написания этого обучающего курса PHP Mailer умел:

Разработчики PHPMailer

  • Brent R. Matzelle
  • Patrice Fournier
  • Chris Ryan
  • Cem Hurturk
  • Tom Klingenberg
  • Jaime Bozza

Готовим PHPMailer для использования

Теперь, когда все файлы на своих местах, давайте создадим файл конфигурации нашего проекта.

Создание и использование файла конфигурации

Одна из главных вещей, которую я люблю делать перед созданием сайта – это написание файла конфигурации, он будет содержать настройки к которым я, возможно, буду обращаться много раз. И так, я создаю файл с название config.php в /home/mywebsite/public_html/config.php. Создаем внем массив с названием $site с моими ключами и значениями, которые я буду использовать в дальнейшем. В этом руководстве я опишу переменные, которые мы будем использовать в классе PHPMailer. Вот пример моего файла config.php:

Этот пример очень прост, чтобы объяснять его. Далее мы продолжим свою работу и будем брать эти настройки по мере надобности.

Создаем класс, расширяющий PHPMailer

Сразу подчеркну, что вы должны создать класс расширения, это позволит упростить вам жизнь, далее я покажу как.

Класс расширения вызовет класс PHPMailer() и установит начальные значения, такие, как Email адрес от имени которого вы будете посылать письма, настройки почтового сервера, и так далее.

Каждый из этих параметров берется по умолчанию из файла config.php, но вы также можете переписать их при вызове нашего класса расширения. Таким образом, если вы не переопределите какой-либо из параметров в классе расширения, то он будет взят поумолчанию из файла config.php, и вам не надо каждый раз переопределять эти параметры. В этом и красота данного подхода!

Взгляните на наш класс расширения:

Далее мы рассмотрим этот код.

Разберем класс FreakMailer

Наш класс, показанный выше, очень прост. И вам необходимо обладать только базовыми навыками ООП, чтобы использовать его. Давайте разберемся.

Сначала нам необходимо подключить класс PHPMailer (файл class.phpmailer.php в директории lib). Это позволяет нам расширить класс PHPMailer, потому что делает объект доступным. Вы могли бы подключить его и в другом месте, но здесь это наиболее эффективно.

Структура управления классом

Далее, мы определяем структуру управления классом и даем ему имя при расширении класса PHPMailer.

Переменные класса

Идем дальше. Теперь мы определяем внутренние переменные. Большинство из них установлены поумолчанию в NULL, чтобы позже мы могли их переопределить, если есть необходимость заменить значения, установленные в config.php.

Давайте рассмотрим эти переменные:

После определения переменных, мы с вами можем обсудить функцию FreakMailer().

Функция FreakMailer()

Эта функция, в основном, настраивает начальные значения для класса PHPMailer, чтобы посылать почту.

Сначала мы вызываем массив $site из файла config.php, чтобы иметь возможность использовать его в пределах данной функции и класса. Чтобы сделать это есть два способа: передать массив при вызове класса или сделать массив глобальным. Последний способ самый легкий и он работает, поэтому его и используем!

Все дальнейшие действия – это, в основном, определение значений переменным класса PHPMailer. Если внутренняя переменная ($this->setting) не определена, мы берем значения из файла config.php. Я уже упоминал о том, что вы можете переопределить значения из config.php, здесь мы проверяем это.

Отправка электронной почты средствами PHPMailer

Предварительная работа сделана и теперь у нас есть все, чтобы посылать письма средствами PHPMailer.

Первоначальное испытание

Это испытание очень важно, потому что в рамках данной статьи мы будем постоянно возвращаться к приведенному здесь коду. Если данный код у вас не заработает, перечитайте этот материал сначала и снова попробуйте. Наш первый пример мы сохраним в файле mailtest.php, который положим в корень нашего проекта. Вот его содержимое:

Давайте разберем этот код для лучшего его понимания.

Сначала мы подключаем наш конфигурационный файл, чтобы иметь доступ к массиву $site.

Далее, подключаем класс FreakMailer.

Теперь необходимо инициализировать наш класс расширения, а также класс PHPMailer.

Теперь PHPMailer готов и мы идем дальше.

Задаем тему письма и его содержание.

Если вы используете в качестве письма обычный текст, то необходимо разделять строки или . И вы должны использовать двойные кавычки при определении переменной $mailer->Body. Если вы используете одинарные кавычки, то перенос текста с одной строки на другую возможен с помощью клавиши .

Теперь необходимо добавить адрес получателя.

Далее, мы очищаем список адресатов и список вложений.

Основные проблемы

Вот список некоторых (типичных) проблем, которые могут возникнуть у вас при отправлении почты при помощи PHPMailer (вероятнее всего, эти проблемы у вас возникли бы и при обычном отправлении писем):

  • на вашей машине не установлено или не запущено ни одного SMTP сервера;
  • неправильные настройки внутри PHP скрипта, перечитайте обучающий курс еще раз;
  • Сервер Apache не разрешает релей через SMTP сервер на локальной машине (типичный случай);
  • вы не правильно определили получателя письма.

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

Использование дополнительных возможностей PHPMailer

Если вы уже здесь, но не читали при этом предыдущего материала – вернитесь и прочитайте, потому что здесь мы будем заниматься расширением базового примера.

PHPMailer имеет множество особенностей, например, добавление вложений, рассылка по списку адресатов и др. В этой части нашего материала мы с вами посмотрим, как это выглядит на практике.

Обработка адресов электронной почты

PHPMailer поддерживает много особенностей Адреса электронной почты, типа "Для" TO, "от" FROM и списков получателей, точная копия CC и Слепая точная копия BCC, Reply-TO и др. Давайте посмотрим, как использовать эти особенности.

Помните, что мы опираемся на основной пример, приведенный выше.

Добавление адреса отправителя (FROM)

В нашем основном примере адрес отправителя уже задан посредствам config.php и класса расширения, но вы в любой момент можете его переопределить. Например:

Если не определить FromName, то большинство почтовых клиентов в качестве имени подставят емаил.

Добавление адреса для ответа (Reply-To)

Поумолчанию, адрес для ответа совпадает с адресом, с которого вы отослали письмо (FROM). Однако вы можете определить разные адреса для ответа на ваше письмо:

ЗАМЕЧАНИЕ:

Вы можете задать несколько адресов для ответа. Для этого необходимо продублировать приведенный выше код столько раз, сколько вы имеете адресов (не забудьте в примере менять адреса на нужные вам).

Добавление нескольких получателей

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

ЗАМЕЧАНИЕ:

Не рекомендуем пользоваться этим методом для рассылки по списку адресатов! Каждый получатель вашего письма будет видеть ВЕСЬ список получателей, а, затем, сможет использовать его по своему усмотрению. Позже мы расскажем как правильно отсылать письма по списку адресатов.

Добавить получателей точной копии (CC)

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

Добавление получателей слепой точной копии (BCC)

Невидимых получателей или BCC можно добавить используя следущую функцию:

Требование подтверждения прочтения

Если вы хотите запросить у человека, читающего ваше письмо, подтверждение о прочтении, подайте следующую команду:

Теперь, когда мы рассмотрели все адреса для отправки почты, давайте посмотрим, как посылать письма ввиде HTML!

Отправление писем ввиде HTML при помощи PHP и PHPMailer

Формирование HTML письма – это одна из самых сложных задач при отправке почты средствами PHP. Настройка MIME заголовков и построение HTML – нелегкая задача и требует дополнительных знаний и исследований. Однако, PHPMailer сделает вашу жизнь проще, далее, мы покажем как это реализуется.

Важное замечание относительно почты ввиде HTML

Прежде чем мы приступим к отправке таких писем, я хотел бы, чтобы вы поняли, что важно знать о том, каким образом должны подключаться изображения и стили CSS, и т.д. Простое правило состоит в том, чтобы хранить эти файлы на сервере, а в письме давать полные ссылки на них. Если вы сходите сума и добавляете все эти файлы к письму, то готовьтесь к головной боли. Например, тело моего письма выглядит примерно так:

Как вы видете, я сделал каждый URL полным, а не сокращенным относительно моего документа. Если этого не сделать, то ваши изображения не будут грузиться и пользователь их не увидит!

Идем дальше, теперь нам необходимо отослать наше письмо. Для этого нам необходимо определить тело нашего письма и задать isHTML настройки. Следующий пример расширяет первоначальный базовый пример.

Дополнительные "тела" письма

Прикрепление файлов к письму

Прикрепить файл к письму – это чень легкая задача, если вы используете PHPMailer. Просто добавьте их письму точно также, как вы добавляли адреса. Вот пример:

Функция AddAttachment имеет 4 аргумента:

  • путь до файла;
  • имя файла;
  • кодирование;
  • тип заголовка.

Путь до файла, естественно, полный путь до файла на диске, имя файла – название файла, который вы хотите прикрепить, кодирование – поумолчанию base64, тип заголовка – это тип заголовка, который вы хотите послать – поумолчанию – Application/octet-stream.

Как видите, все очень легко! Давайте перейдем с вами к использованию SMTP.

Использование внешнего(их) SMTP для работы с почтой средствами PHP

Сначала давайте обсудим использование внешнего SMTP вместо локального. В базовом примере мы с вами сделали config.php, где задали несколько вариантов для SMTP сервера. Если вы хотите указать больше SMTP серверов – сделать это можно также расширив config.php, установив $site['smtp_enabled'] = 'enabled'; (включено).

В $site ['smtp_host'] вы можете расширить список SMTP серверов, разделяя их точкой с запятой. Например:

Как я понимаю, PHPMailer попытается послать почту через первый сервер, если это не удается – через второй и так далее.

ЗАМЕЧАНИЕ:

Помните, что вы всегда можете включить авторизацию через SMTP или поменять порт в файле config.php.

Важное замечание, обращаю ваше внимание, что для отправки писем через SMTP необходимо использовать не стандартную функцию Send(), а функцию SMTPSend(). Например:

Проблемы с отправкой через SMTP

Есть много вариантов возникновения ошибок при работе с SMTP, в основном, все они касаются прав доступа:

  • имеет ли ваш хостинг разрешение на отправку почты через указанный SMTP?
  • Возможно, перед подключением по SMTP необходимо подключиться по протоколу POP (сначала скачать – потом отправлять);
  • вах хостинг требует авторизации соединения;
  • вы уверены, что вы ввели правильные параметры пользователя и пароля?

К сожалению, я не уверен, что PHPMailer поддерживает соединение по протоколу POP перед соединением по SMTP. Если это создает проблему – свяжитесь со своим администратором и попросите хозяина релея прописать ваш IP адрес для сервера.

Использование qmail и Sendmail

Если вы хотите обойти функцию mail() PHP и использовать бинарные программы для работы с почтой, то вам необходимо определить тип почтового сервера, а затем PHPMailer запустит указанный бинарный файл, что, возможно, немного ускорит операции. Пример:

Как видите, это довольно легко! Давайте перейдем к построению простого списка адресатов.

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

Теперь, когда вы уже имеете достаточное представление о работе PHPMailer, давайте рассмотрим некоторые особенности списков рассылки. Выскажу несколько соображений о том, что вам может понадобиться при рассылке: настройка темы письма, тела письма. И, что наиболее важно, необходимо скрыть адреса получателей друг от друга.

Следующий пример предполагает, что у вас уже есть некоторая база данных со списком адресов и вы знаете как соединиться с базой MySQL. Пока мы предположим, что вы имеете что-то следующей структуры:

  • Имя
  • Фамилия
  • Электронный адрес
  • Тип письма (text/html)

Предположим, что вы имеете 50 пользователей и хотите сделать настраиваемую рассылку по этим адресам. Следующий пример поможет вам в этом:

Разбор кода списка рассылки

Первая часть такая же, как и в нашем первом примере – мы подключаем необходимые файлы.

Далее, мы определяем тело нашего письма. Вы можете также читать его из файла, но мы, для простоты, держим его внутри этого скрипта.

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

Далее, мы инициализируем класс для работы с почтой.

Далее, мы получаем данные об адресатах из базы данных. И организуем цикл, в котором получаем последовательно каждый ряд в объект.

Теперь мы дошли до места, где происходит непосредственная отсылка почты. Черезвычайно важно разобраться в том, что мы здесь делам. Первая часть кода в основном занимается формированием переменной $member_name, которая будет содержать все данные текущего пользователя.

Следующая часть кода определяет предпочтения пользователя – HTML или plain-text. Если пользователь предпочитает HTML, то мы пошлем ему письмо ввиде HTML с включенным телом текстового письма. В противном случае – пошлем только текстовый вариант.

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

Наконец, мы отсылаем письмо и очищаем адреса в объекте $mailer от любых вложений.

ЗАМЕЧАНИЕ:

Удостоверьтесь, что вы используете функции $mailer->ClearAddresses() и $mailer->ClearAttahements(), иначе адреса пользователей будут добавляться в конец списка.

Подведем итог

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

Если вы настроите данный класс правильно, то в последующем, при создании других сайтов, вам не надо будет тратить свое время.

Я надеюсь, что вы найдете время посетить сайт класса PHPMailer и почитать документацию к нему и FAQ. Очень важно понять, как устроен класс и ознакомиться со взглядом разработчиков на него. К тому же, на сайте есть другая большая обучающая статья и некоторые примеры.


Отличная статья! Может сделаете еще инструкцию по swiftmailer? Тоже очень хороший класс и работает быстрее phpmailer когда доходит речь до очень больших объемов.


Спасибо. Очень полезная статья. А как сделать рассылку по списку пользователей с учетом времени посещения? К примеру, мне надо давать периодические оповещения тем пользователям, которые не посещали сайт в течение 5-ти месяцев.



Тут я хочу сразу немного огорчить Вас - CSS в привычном для Вас виде не стоит использовать. Mail, Yandex, Google, Outlook - выкидывают стили из писем. Однако, есть выход.

Выполним несколько условий:
1) Надеюсь не нужно пояснять, что используем Content-type: text/html

2) Вспоминаем, что такое table вёрстска. Теперь все стили вписываем только в неё. Можно также вспомнить center, font.


С div то же самое


3) В примере выше с отправкой письма приводилась данная строка. Так вот её не забываем

4) Используем HTML 3.2. Вставляем в начало html письма.


5) В качестве background - можно цвет. Хотите фон-изображение - тогда делайте весь текст и фон изображением. Как вариант: можно указать background-image для body.

6) У единственной в ячейке картинки в Gmail появляется 3px отступ снизу, чтобы избежать этого указываем ей

В данной статье рассмотрена отправка почты из PHP с детальным описанием функции mail(), использования русских символов и защиты от спама.

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

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

Способ кодирования указывает на то, каким именно образом русские символы будут преобразованы в безопасный набор. Способа определяется два: так называемый "Q-encoding" (обозначается одной буквой "Q") и "Base64" (обозначается одной буквой "B").

Функция mail()

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

а затем передает ее на обработку стандартной 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 " (обратите внимание на формат строки: "минус-эф", а затем без пробелов электронный адрес).

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

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

Борьба с этим явлением может вестись двумя способами:

Проверка всего пользовательского ввода и фильтрация опасных символов (т.е символов "\r" и "\n"). Эти символы нужно либо заменять на пробелы, либо отказываться обрабатывать некорректно введенные параметры. Например, замену можно выполнить так:

Выполнение кодирования Base64, помимо прочего, защищает и от спамеров, т.к. "вытягивает" закодированный текст в одну строку.

Как все это сделать проще

Использование готовых решений для отправки почты. В качестве примера можно привести класс PHPMailer, который легко позволяет реализовать все возможности, описанные выше, и еще целый ряд того, о чем не было упомянуто.

Почтовая программа. Отправка почты на PHP

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

Для отправки письма через SMTP-сервер необходимо:

  • данные для доступа к SMTP-серверу;
  • e-mail получателя;
  • письмо и его заголовок;
  • системные заголовки.

С электронным адресом получателя, текстом письма и его заголовком, проблем нету. Данные для доступа мы имеем, обычно это хост, порт и пара логин/пароль. Остается составить системные заголовки, в них то и кроется вся сложность исходной задачи.

Создание системных заголовков

Класс для отправки почты на PHP

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

Отправка пробного письма

Для рассылки, почти, все готово, остается проверить, отправив пробное письмо.

На этом с отправкой почты заканчиваем, если возникли вопросы, задаем их в комментариях.

PHP класс для отправки E-mail

Путь до файлов должен быть абсолютным.
Общий размер файлов не должен превышать 25 Мб.

Рассылка на адреса из массива

Сохранение копии письма в файле .eml

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

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

Для отправки письма через SMTP-сервер необходимо:

  • данные для доступа к SMTP-серверу;
  • e-mail получателя;
  • письмо и его заголовок;
  • системные заголовки.

С электронным адресом получателя, текстом письма и его заголовком, проблем нету. Данные для доступа мы имеем, обычно это хост, порт и пара логин/пароль. Остается составить системные заголовки, в них то и кроется вся сложность исходной задачи.

Создание системных заголовков

Класс для отправки почты на PHP

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

Отправка пробного письма

Для рассылки, почти, все готово, остается проверить, отправив пробное письмо.

На этом с отправкой почты заканчиваем, если возникли вопросы, задаем их в комментариях.

Читайте также: