Безопасный способ отправки почты через PHP многим пользователям

позвольте мне объяснить, что я имею в виду мой титул. Скажем, что, например, я создаю небольшую систему электронной коммерции для одного интернет-магазина/каталога. Есть возможность для клиентов выбрать, хотят ли они получать информационные бюллетени или нет. Если они это делают, то логически мыслящие информационные бюллетени должны быть отправлены сразу же, как информационный бюллетень сформирован и готов.

конечно, это можно сделать просто, извлекая все указанные электронные письма пользователя из базы данных и используя for цикл для отправки почты через

7 ответов


нет причин, по которым вы не могли бы написать его на PHP, хотя я бы не сделайте его частью процесса webrequest / HTTP. Я успешно реализовал для 500 000 подписчиков на рассылку (в зависимости от доступных локальных данных, так как это был проект для конкретного местоположения). Это был внутренний проект, поэтому, к сожалению, для вас нет кода / пакета, но некоторые указатели я наткнулся:

настройка доставка

  • начал выходите с самим phpmailer, чтобы позаботиться о форматировании, кодировании содержимого и заголовков,добавлении вложений и т. д. Эта часть работает хорошо, и я не хотел бы писать это с нуля.
  • "отправка" самого письма-это просто установка некоторого флага в базе данных, следует ли / как / что отправлять (часть) подписчикам.
  • после того, как этот флаг установлен, он будет автоматически подхвачен cronjob, без участия веб-сервера.
  • I начал с сильно загрязненной базы данных с миллионами адресов электронной почты, из которых много были очевидны недействительны, поэтому первое, что нужно было проверить все адреса электронной почты для формата, а затем для хоста:
    • filter_var($email, FILTER_VALIDATE_EMAIL); над подписчиками (и сохранение результата, очевидно)избавились от первых нескольких сотен тысяч недействительных писем.
    • разделение хоста (и хранение имя хоста) из писем и проверки этого (есть ли у него MX или хотя бы запись A в DNS, но имейте в виду: вы можете отправить электронное письмо на IP-адрес foo@[255.255.255.255], Так что держите их действительными)) избавился от хорошей части больше. В emailaddresses здесь не навсегда отключены, но с флагом состояния, который указывает, что они отключены из-за доменного имени / ip.
    • скрипты были изменены на требуются действительные адреса электронной почты по подписке / перед вставкой, эта ерунда 'вы Aint собираюсь сделать это@anywhere' подписка-загрязнение в базе было просто смешно.
  • теперь у меня появился список адресов электронной почты, которые могли быть действительными. Есть, по сути, 3 способа обнаружения недопустимых адресов (имейте в виду,все может быть временным):
    • они немедленно отклоняются сервером.
    • ранее определенный сервер просто не слушает трафик.
    • они отскочили еще долго после того, как вы думали, что доставили их.
  • странная вещь, отскоки, которые каждый почтовый сервер, похоже, имеет другой формат и были адом для разбора сначала, в конечном итоге довольно легко захватить с помощью VERP. Вместо того, чтобы разбирать целые электронные письма, выделенный адрес электронной почты (назовем его mailer@example.com) был настроен на то, чтобы вместо доставки в почтовый ящик, передать его через команду, и если мы отправили электронное письмо пользователю@server.дву Return-Path было назначено на mailer+user=server.tld@example.com. Легко разбирается при получении, а после Сколько отскоков (почтовый ящик не может существовать, почтовый ящик может быть заполнен (да, еще!), п.) вы объявляете emailaddress непригодным для использования до вас.
  • теперь прямое отрицание сервером. Вероятно, мы могли бы пойти с правильной настройкой некоторых MTA и/или написания плагинов для них, но поскольку электронные письма были чувствительны ко времени, и мы должны были иметь абсолютный настраиваемый контроль за рассылкой в течение последнего времени доставки (после чего электронная почта больше не представляла интереса для пользователя), дросселирование на принимающий сервер и вообще все, это заняло бы примерно столько же времени, сколько написание почтовика на PHP, который мы знали лучше, который использовал протокол SMTP непосредственно для сокета 25 на принимающих серверах. С минимальным количеством усилий, возможность другого транспорта, то выбор по умолчанию в PHPMailer был встроенный. Протокол SMTP на самом деле довольно прост, но есть некоторые оговорки:
    • много получать сервер применить серый список: большинство спам-ботов не будет действительно заботиться, если приходит конкретная почта,они просто сбивают их. Таким образом, если неизвестный / еще не доверенный отправитель отправит почту, она будет временно отклонена. Поймайте это (обычно код 451) и поместите электронное письмо в очередь для последующей повторной попытки.
    • почтовый сервер, особенно крупных интернет-провайдеров и бесплатных услуг (gmail, hotmail / msn / live и т.д.) не выдержит поток почты без отпора: после первой пары сотен / тысяча, они начинают отвергать тебя. Об этом позже.

получаю скорость

  • теперь у нас была система доставки, которая работала, но она должна была быть быстро. Отправка 10,000 писем в час-это нормально, если у вас есть только 10,000 адресов для отправки, но минимум, который мы требовали, был около 200,000 в час. Начало его было выделенным сервером (который на самом деле может быть довольно низким, независимо от того, что вы у, Большая часть времени, затрачиваемого на доставку электронной почты, находится в сети, а не на вашем сервере).
  • кэширование IP-адресов: помните все те IP-адреса, которые мы запрашивали у имен хостов в адресах электронной почты? Очевидно, мы сохранили их, и поиск их IP-адресов снова и снова вызывает значительное отставание. Однако IPs может измениться: запись DNS там, другой MX в другом месте... данные быстро устаревают. Большую часть времени сервер фактически ничего не отправляет (информационные бюллетени подписки приходят в виде пакетов очевидно), с низким приоритетом cronjob работает проверка всех имен хостов с устаревшим IP (мы выбрали более старый, чем 1 день как устаревший) для IP-адреса,включая те, которые ранее не имели (новые домены регистрируются все время, так почему домен не должен стать доступным на следующий день после того, как кто-то уже с энтузиазмом подписался на его/ее новый адрес электронной почты? Или проблемы с сервером с некоторыми домен решаются и т. д.). На самом деле отправка электронной почты теперь не требуется больше домена поиски.
  • повторное использование SMTP-соединения: настройка соединения с сервером занимает относительно большую часть времени для доставки электронной почты, когда вы говорите непосредственно с портом 25. Вам не нужно устанавливать новое соединение для каждого письма, вы можете просто отправить следующее по тому же соединению. Немного trail-and-error привело к установке по умолчанию здесь около 50 писем на соединение (предполагая, что у вас есть много или больше для домена). Однако, на отказе emailaddress закрытие и повторное открытие соединения для повторной попытки иногда помогало. В общем, это действительно помог ускорить процесс.
  • какой-то очевидный, настолько очевидный, что я почти забыл упомянуть об этом: было бы пустой тратой создавать тело письма на месте: если это общая почта, подготовьте тело (я изменил PHPMailer несколько, чтобы иметь возможность использовать кэшированное письмо), возможно, за несколько дней до (Если вы знаю вы собираетесь отправить на почту , и ваш сервер работает на холостом ходу, почему бы не подготовить их уже в среду? Если он персонализирован, вы все равно можете подготовить его заранее, учитывая достаточно времени, если нет, по крайней мере, есть неперсонифицированные части, ожидающие выхода.
  • несколько процессов. Я упоминал, что большая часть времени, необходимого для доставки электронной почты, тратится на сеть? Один процесс рассылки почти не получает максимальную отдачу от вашего почтового сервера, едва заметная загрузка и письма вытекают. Поиграйте с рядом процессы рассылки различных частей очереди, чтобы увидеть, что правильно для вашего сервера / соединения, но помните 2 очень важные вещи:
    • различные процессы делают вас очень уязвимыми для условий гонки: будьте чертовски абсолютно уверен у вас есть полностью защищенная система, которая будет никогда отправить то же письмо дважды (трижды, даже больше). Он не только серьезно раздражать пользователей, ваш spamrating поднимается на ступеньку выше.
    • сохранить доменов, где возможно: случайный выбор из очереди Вы потеряете преимущество сохранения открытого соединения с сервером, получающим электронную почту для домена.

избежать отклонений

  • вы собираетесь отправить много писем. Это именно то, что делают спамеры. Однако вы не хотите, чтобы вас считали спамером (в конце концов, вы не являетесь, не так ли)? Существует ряд механизмов, которые полностью увеличат ваш надежность получающих серверов:
  • иметь правильный обратный DNS: процессы проверки DNS, принадлежащие IP, который отправляет электронную почту, как это очень много, если домены второго уровня совпадают: вы отправляете почту от имениexample.com? Убедитесь, что обратный DNS вашего сервера-это что-то вродеsomename.example.com.
  • опубликовать записи SPF для вашего домена: явно укажите, что машина, используемая для отправки массовой электронной почты, разрешено и ожидается отправка почты с заголовками / Return-Path.
  • помните, отвергает: серверы не любят повторять вам снова и снова, что разные адреса электронной почты не существуют. Либо автоматические механизмы, либо даже человеческие администраторы заблокировали наш сервер, пока мы работали со всеми неподтвержденными адресами электронной почты, которые существовали (больше не существовали). Мы не использовали двойную опт-ин до тех пор, пока позже, поэтому база данных была загрязнена опечатками, люди переключали IPs и тем самым адрес электронной почты, шутки адреса электронной почты и так далее. Не забудьте захватить этих инвалидов, и учитывая достаточно или разорвать достаточно неудач,отписаться от них. Они не делают вам ничего хорошего, они захватывают ресурсы, и если они действительно хотят, чтобы вы отправили почту, и почтовый ящик станет доступен позже, им просто придется повторно подписаться.
  • DKIM-еще один механизм, который может повысить вашу надежность, но поскольку мы его еще не реализовали (пока), я не могу много рассказать вам о что.
  • MX records: некоторым серверам все еще нравится, если ваш отправляющий сервер также является принимающим сервером для домена. Как это было в то время, у нас был только 1 MX, и поскольку почтовый сервер все еще не был очень занят, мы окрестили его резервным MX-сервером для домена. Обычный MX-сервер был не сервер, отправляющий подписки, так как очень раздражает временная блокировка сервером, на который вы пытаетесь отправить важное электронное письмо (клиентам и т. д.) потому что ты уже отправил кучу менее важных писем. У него есть самое высокое предпочтение как получение MX, но в случае неудачи у нас был хороший бонус, что наш сервер отправки подписки по-прежнему будет резервным для доставки, поэтому в кризис мы все равно могли бы добраться до него, предотвращая неудобные отскоки клиентам, пытающимся связаться с нами.
  • расскажи им о себе. Серьезно. Много крупных игроков в бесплатные адреса электронной почты, как live.com предложите вам возможность зарегистрироваться каким-либо образом, или иметь некоторые точка контакта, чтобы обратиться за помощью и поддержкой, если ваши письма будут отклонены. У вас есть законная причина отправлять так много писем, и это правдоподобно, что у вас есть много подписчиков, скорее всего, они серьезно увеличивают количество писем, которые вы можете отправить на свой сервер в час. Скудная тысяча может стать где-то среди десяти тысяч или даже выше, если вы достаточно убедительны и честны. Могут быть контракты, требования, которые вы должны выполнить, и обещания, которые вы должны сделать (и сохранить), чтобы быть разрешены этот. ISP-это отдельный бренд, и каждый другой игрок отличается. Не беспокойтесь, звоните им обычно, потому что в 99% случаев единственные номера, которые вы можете найти, будут иметь только людей, желающих устранить неполадки вашего интернет-соединения, которые понимают (или разрешены) мало что еще. Ан abuse@ адрес электронной почты-хорошее место для начала, но посмотрите, можете ли вы углубиться в более точный адрес электронной почты откуда-то. Будьте точны, честны и полны: примерно сколько подписчиков у вас есть адрес электронной почты с этим провайдером, как часто вы пытались отправить их по почте, какие ошибки или отказ вы получите, как процесс подписки & unscubscribe как, и какая вы на самом деле предоставляете своим клиентам. Кроме того, будьте любезны: насколько жизненно важно отправлять эти письма вашему бизнесу, паниковать по этому поводу и заявлять о страшных потерях, их не касается. Вежливое изложение фактов и пожеланий, и ... --6-->прошу могут ли они помочь, а не требовать решения идет очень долго путь.
  • дросселирование: сколько вы ни пытались, какой-то сервер будет принимать от вас только определенное количество почты в час и/или день. Изучите эти цифры (мы все равно регистрируем успехи и неудачи), установите их в разумное значение по умолчанию для обычных доменов, установите согласованные ограничения для более крупных игроков.

избегая быть помеченным как спам

  • Первое правило: не спамить!
  • Второе правило: никогда! Не "один раз", не "они не подписались, но это может быть сделка всей жизни для них", не с лучшими намерениями, люди должны были попросить ваши электронные письма.
  • очевидно, настройте правильный механизм двойной подписки.
  • PHPMailer устанавливает правильные заголовки самостоятельно,
  • настройте простой механизм отмены подписки через интернет (включите ссылку на него в mail), возможно, также электронная почта и customerservice, если у вас есть. Убедитесь, что обслуживание клиентов можете отписаться от людей напрямую.
  • как было сказано ранее: отменить подписку (чрезмерно) не удается и отскакивает.
  • избегайте спам "дело всей жизни" формулировки.
  • используйте url-адреса в своих письмах экономно.
  • избегайте добавления ссылок на домены вне вашего контроля, если вы не абсолютно уверены, что можете доверять их Не спам, если даже тогда...
  • предоставить пользователю значение: помечается как спам взаимодействие с пользователями в Google/yahoo / live webmail серьезно вредит будущим успехам (на сайте Примечание: Если вы зарегистрируетесь, live/msn/hotmail будет пересылать вам всю почту, отправляемую вашим доменом, который помечен как спам пользователями. Научитесь любить его, и как всегда: отпишитесь на них, они явно не хотят вашего торгового центра и вредят вашему спам-рейтингу).
  • мониторинг черных списков для вашего IP. Если вы появитесь на одном из них, это до свидания, так что immidiate действие в обоих очищая свое имя и определение случая требуется.

измерение успеха

  • со всем процессом под вашим контролем, вы достаточно уверены, что письмо закончилось где-то (хотя это может быть битбакет MX или папка спама), или вы зарегистрировали сбой и причину. Это заботится о "фактически доставленных" номерах.
  • некоторые люди будут пытаться убедить вас, чтобы добавить ссылки на онлайн-изображения на ваши электронные письма (реальный или знаменитый прозрачный gif 1x1), чтобы измерить, сколько людей на самом деле читают вашу электронную почту. Поскольку высокий процент блокирует эти изображения, эти цифры в лучшем случае шаткие, и мы считаем, что мы просто не должны беспокоиться о них, их числа совершенно ненадежны.
  • ваш лучший выбор для измерения фактического успеха намного проще, если вы хотите, чтобы пользователи что-то делали. Добавьте параметры к ссылкам в почте, чтобы можно было измерить количество пользователей на сайте вы связались, выполнили ли они нужные действия (посмотрели видео, оставили комментарий, купили товар).

в целом, со всеми журналами, пользовательским интерфейсом, настраиваемыми настройками для домена/электронной почты / пользователя и т. д. Нам потребовалось около 1,5 человеко-месяца, чтобы построить и сгладить причуды. Это может быть довольно инвестицией по сравнению с аутсорсингом электронных писем, это может быть не так, все зависит от объема и самого бизнеса.

теперь, пусть пламя начнется, что я был дурак писать MTA в PHP, я для одного полностью наслаждался этим (что является одной из причин, по которой я написал это огромное количество текста), и чрезвычайно универсальные возможности ведения журнала и настройки, оповещения на хосте на основе процента сбоев и т. д. делают жить Ох так легко;)


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

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

  • используя неправильные заголовки.

  • обработка недоставленных сообщений

  • тайм-аут сценария из-за притока писем.

Edit:

наверное, не тот ответ, который вы ищете. Но я настоятельно рекомендую вам инвестировать во что-то вроде Монитор Кампании или Почта Шимпанзе. Поскольку этот процесс не для образовательных целей, а для коммерческих, я бы сильно предлагаю вышеуказанные услуги.


Я получил ваш вопрос, но прежде чем ответить, давайте я перейду к обычным соображениям. Во-первых, я настоятельно рекомендую использовать службу, такую как Mail Chimp. Это своего рода бесплатно для небольших рабочих мест и имеет много интересных функций, таких как отслеживание того, сколько писем было открыто, сколько было нажато, сколько не удалось доставить... Подумайте о том, чтобы сделать себе одолжение и не изобретать колесо.

теперь, чтобы узнать цель, давайте перейдем к ответу на ваш вопрос.

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

сохраните все входные данные в таблицу базы данных, с полем "isValid", установленным по умолчанию как false, и любым уникальным хэшем. Затем вы отправляете подтверждение по электронной почте, со ссылкой (с хэшем генерируется) для confimation, который при нажатии сделает флаг "isValid" true и ссылка для отмены (всегда отправляйте эту ссылку отмены во всех ваших электронных письмах).

Это то, что делают магазины и серьезные сайты. Все, что заставляет ваших клиентов / посетителей получать, является плохой моральной практикой (т. е. спамом).

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

Я знаю, вы должны спросить сам, если я неправильно понял твой вопрос. Нет, я не знаю, технические вещи приходят сейчас.

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

эти накладные расходы на подключение проблема, которую люди называют плохой практикой с точки зрения программирования. Использование решения SMTP / IMAP лучше, поскольку оно оптимизирует этот процесс.

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

ну, PHP сохраняет статус " запрашивать почтовый сервер для отправки, почтовый сервер отправленный." Если почтовый сервер отправил ваше сообщение, PHP вернет true. Период.

Если клиент не смог получить или отклонить, вы должны проверить заголовки электронной почты и статус электронной почты. Они находятся на сервере электронной почты. Опять же, эти сведения могут быть доступны с расширениями SMTP/POP/IMAP, а не с почтовой функцией.

Если вы хотите пойти дальше, прочитайте документы IMAP, найдите классы электронной почты (phpclasses.org, груша и pecl-лучшие места для изучения).

экстренная подсказка: RFCs может быть полезно, Так как вы можете лучше понять, какие почтовые серверы действительно разговаривают друг с другом.

дополнительный совет 2: доступ к вам gmail или ymail и проверить ваши отправленные/полученные сообщения для их "полной версии" и прочитать его заголовки. С ними можно многому научиться.



просто используйте PHP Mail и изучайте МВФ и как построить пользовательские заголовки вы можете прикрепить четвертый параметр, exmaple следует

<?php
// multiple recipients
$to  = 'aidan@example.com' . ', '; // note the comma
$to .= 'wez@example.com';

// subject
$subject = 'Birthday Reminders for August';

// message
$message = '
<html>
   ...
</html>
';

// To send HTML mail, the Content-type header must be set
$headers  = 'MIME-Version: 1.0' . "\r\n";
$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";

// Additional headers
$headers .= 'To: Mary <mary@example.com>, Kelly <kelly@example.com>' . "\r\n";
$headers .= 'From: Birthday Reminder <birthday@example.com>' . "\r\n";
$headers .= 'Cc: birthdayarchive@example.com' . "\r\n";
$headers .= 'Bcc: birthdaycheck@example.com' . "\r\n";

// Mail it
mail($to, $subject, $message, $headers);
?>

источник:http://php.net/manual/en/function.mail.php


создайте подсистему очереди почты, которая может включать такие таблицы, как mail_queue, mail_status, mail_attachments, mail_recipients и mail_templates и т. д...


вы можете рассмотреть PHPMailer http://phpmailer.worxware.com/index.php?pg=exampleasendmail

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

Я не думаю, что улавливание ошибки "доставка почты не удалась" возможно через php, за исключением того, что вы используете PHPMailer через SMTP и время от времени следите за любой формой возвращаемого сообщения получатель из вашей коллекции исходящей электронной почты.