Здравствуйте, дорогие читатели. Решил поведать Вам о своих проблемах с Zend_Mail и поделиться их решением.
Программировал как-то я уведомления о новых комментариях на почту. Использовал Zend_Mail и натолкнулся на целую кучу проблем связанных с этим. Вот они:
- Как организовать мгновенные массовые рассылки?
- Проблемы с кодировками писем;
- Проблемы с вложениями в письмах;
Давайте вместе разложим все по полочкам и решим эти проблемы. Итак, поехали!
Быть или не быть?
Для реализации рассылок о новых комментариях к статьям на почту, я поставил себе такие задачи:
- После добавления комментария, человек, пожелавший подписаться на рассылку, заносится в БД;
- Далее происходит выборка подписчиков и мгновенная рассылка комментария (тут возник вопрос: как сделать это, чтобы отправитель комментария не чувствовал задержек при рассылке?);
- Письма должны быть в UTF-8 (вопрос: почему на почту приходят крякозябры?);
- Нужно красиво оформить содержимое письма (вопрос: а как вставить картинку в письмо и вообще красиво оформить его?).

Первое, не относится к теме поста, поэтому рассматривать этот пункт не буду. Так что сразу перейдём ко второму.
Для мгновенной рассылки нужно использовать Zend_Mail_Transport_Smtp. Такое решение является самым быстрым из доступных на сегодняшний день, тем более что такой способ рассылки более гибче в плане настроек. Пример использования далее в статье.
Кодировки писем - решаем все вопросы
Третий вопрос я вынес в отдельную часть статьи потому, что он очень важен и актуален на данный момент.
Когда мне пришлось решать вопросы с кодировками в Zend_Mail, я много чего перечитал, пересмотрел и обсудил с людьми. Поняв что готового решения мне не найти – начал искать сам и нашел!
Некоторые программисты высказывали мнение,
что проблема с кодировками в письмах возникает из-за того, что почтовые
клиенты не поддерживают эти кодировки. В частности нарекали на то, что
кодировку UTF-8 корректно воспринимают единицы
почтовых клиентов. Откровенно Вам скажу, что всё это выдумки тех, кто
не справился с задачей.… Когда я решил все вопросы с кодировками -
лично убедился в этом. Правы были те, кто говорил, что собака зарыта в Zend_Mail.
Дело в том, что если при отправке письма указать кодировку и кинуть тексты в этой кодировке, то письма отображаются нормально, но кроме заголовков. Я долго искал решение проблемы. Детально ознакомившись со спецификацией RFC 1522, которой руководствуется Zend_Mail, я понял, что Zend_Mail не правильно разбивает заголовки, просто символом перевода строки, пользуясь константой Zend_Mime:: LINELENGTH (т.е. вставляет символ перевода строки через 72 символа). Благодаря SMTP заглушке, я смог увидеть такую нездоровую вещь и начал уже работать в конкретном направлении.
Я нашел метод, в котором идет работа с заголовками в Zend_Mail. И увидел, что переписав данный метод, вполне реально избавится от неверной разбивки на строки. Я унаследовал класс Zend_Mail и просто переписал нужный метод, поправив в нём все необходимое. Для понимания кода и для того, чтобы обойтись без лишних объяснений, я хорошо задокументировал класс.
Итак, смотрим:
Немножко обьясню. В соответсвии со спецификацией RFC 1522, заголовок должен рабиваться на строки по такому правилу: каждая новая строка, должна быть разделена символом перевода строки и пробелом, после чего, формирование строки должно начинаться с указания кодировки (т.е. предыдущая строка закрывается символом ?=, а новая начинается после символа перевода строки, пробела, и например, такой строчки =?UTF-8?Q?).
Каждая строка заголовка должна раделяться символом перевода строки, пробелом и иметь такой формат:
=?кодировка?Q?значение?=
Теперь при использовании выше приведенного
класса, строка "Комментарий к статье "Практическая реализация паттерна
Singleton на PHP"" превратится в:
После того, как Вы начнете использовать данный класс проблем с крякозябрами в заголовках быть не должно. Этот фикс исправляет все проблемы в HTML-письмах и в обычных текстовых рассылках.
Аттачи (вложения файлов в письмо)

Также мне пришлось разобраться и с вложениями в письмах, например, картинки. Мне советовали с этим не заморачиваться и грузить картинку просто прописав на неё ссылку, но такой способ, увы, не катит. Почему? Дело в том, что некоторые почтовые клиенты блокируют загрузку файлов с внешних серверов и такой способ не надёжный, поэтому я решил, что нужно создавать вложение.
Приступим. Чтобы создать вложение в Вашем письме необходимо:
- Считать файл;
- Преобразовать его в бинарную строку;
- Закодировать;
- Добавить в письмо;
Большинство этих пунктов решает класс Zend_Mime_Part. Вам только нужно будет считать файл, и задать параметры для вложения.
Приведу пример создания вложения и
добавления его в письмо. Код хорошо документирован, поэтому, я считаю,
лишних объяснений не нужно.
Обратите внимание на то, что я указал тип контента не «image/gif», а «application/octet-stream». Я сделал это потому, что некоторые почтовые клиенты отображают картинку в конце письма, а ведь нам нужно просто вложить файл и показать его в нужном месте, а не где захочет почтовик, верно?
Теперь использовать вложенный элемент очень просто. Как вы можете увидеть, я указал свойству id экземпляра объекта Zend_Mime_Part определённый идентификатор. Теперь, когда Вам надо вставить картинку в нужном месте вы можете написать, например:
Видите, как всё просто?
А теперь все вместе!
В качестве итога, я хочу показать Вам полный пример такой почтовой рассылки:
Надеюсь, Вам будет полезна такая информация. Все возражения, пожелания, замечания как всегда жду в комментариях.
P.S. Счастливых Вам новогодних праздников!


, появляются левые знаки...
