Отправка email при помощи PHP

    Сегодня мы поговорим о том, как отправлять email письма с помощью встроенных php функций. Казалось бы — что тут проще? Берёшь функцию mail(), задаёшь ей 3-5 параметров и всё. А вот и нет — тут не всё так просто и при детальном рассмотрении возникает просто огромнейшее количество подводных камней:

    • Кириллица в теме, в тексте письма, в имени отправителя
    • Отправка писем в другой кодировке
    • Использование вложений
    • HTML вёрстка, вставка изображений в тело письма

    Не стоит унывать, если у вас что-то из этого не работает. Для начала, давайте, разберёмся с первыми двумя проблемами. Если написать, например, mail('test@example.com','Привет!','Привет! Как дела?'), то адресат, скорее всего, получит кракозябры.

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

    Content-type: <тип письма>; charset=<кодировка>
    тип письма: text/plain или text/html
    с кодировкой, я думаю, понятно.

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

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

    =?<кодировка>?B?<текст в base64>?=

    Поскольку кодировка php (обычно это utf-8) и кодировка писем (обычно это windows-1251) часто отличаются, то ещё и желательно их перекодировать. Вот функция, которая проводит все необходимые манипуляции:

    1. function mime_header_encode($str, $data_charset, $send_charset){
    2.   if($data_charset != $send_charset)
    3.     $str=iconv($data_charset,$send_charset.'//IGNORE',$str);
    4.   return ('=?'.$send_charset.'?B?'.base64_encode($str).'?=');
    5.   }

    Я всегда был за расширяемость кода, поэтому отправку писем оформил в отдельный класс:

    1. class TEmail{
    2.   public $from_email;
    3.   public $from_name;
    4.   public $to_email;
    5.   public $to_name;
    6.   public $subject;
    7.   public $data_charset='UTF-8';
    8.   public $send_charset='windows-1251';
    9.   public $body='';
    10.   public $type='text/plain';
    11.   function send(){
    12.     $dc=$this->data_charset;
    13.     $sc=$this->send_charset;
    14.     //Кодируем поля адресата, темы и отправителя
    15.     $enc_to=mime_header_encode($this->to_name,$dc,$sc).' <'.$this->to_email.'>';
    16.     $enc_subject=mime_header_encode($this->subject,$dc,$sc);
    17.     $enc_from=mime_header_encode($this->from_name,$dc,$sc).' <'.$this->from_email.'>';
    18.     //Кодируем тело письма
    19.     $enc_body=$dc==$sc?$this->body:iconv($dc,$sc.'//IGNORE',$this->body);
    20.     //Оформляем заголовки письма
    21.     $headers='';
    22.     $headers.="Mime-Version: 1.0\r\n";
    23.     $headers.="Content-type: ".$this->type."; charset=".$sc."\r\n";
    24.     $headers.="From: ".$enc_from."\r\n";
    25.     //Отправляем
    26.     return mail($enc_to,$enc_subject,$enc_body,$headers);
    27.     }
    28.   }

    Вот так мы будем отправлять письма:

    1. //Текстовое письмо
    2.   echo('Plain text email - sending...<br>');
    3.   $email=new TEmail;
    4.   $email->from_email='noreply@konservs.com';
    5.   $email->from_name='Автор ІЇҐЭЄ іїґэє';
    6.   $email->to_email='******@gmail.com';
    7.   $email->to_name='Для Васі';
    8.   $email->subject='Тема ІЇҐЭЄ іїґэє';
    9.   $email->body='Текстовий тестовий лист. Тест: ІЇҐЭЄ іїґэє';
    10.   if($email->send())
    11.     echo('Plain text email - OK.<br>'); else
    12.     echo('Plain text email - Error!<br>');
    13.   //HTML письмо
    14.   echo('HTML email - sending...<br>');
    15.   $email=new TEmail;
    16.   $email->from_email='noreply@konservs.com';
    17.   $email->from_name='Автор ІЇҐЭЄ іїґэє';
    18.   $email->to_email='******@gmail.com';
    19.   $email->to_name='Для Васі';
    20.   $email->subject='Тема ІЇҐЭЄ іїґэє';
    21.   $email->type='text/html';
    22.   $email->body='Тестовий лист в HTML.
    23.     <h1>Header 1 (Заголовок 1)</h1>
    24.     <h2>Header 2 (Заголовок 2)</h2>
    25.     <h3>Header 3 (Заголовок 3)</h3>
    26.     <h4>Header 4 (Заголовок 4)</h4>
    27.     <h5>Header 5 (Заголовок 5)</h5>
    28.     Тест: ІЇҐЭЄ іїґэє';
    29.   if($email->send())
    30.     echo('HTML email - OK.<br>'); else
    31.     echo('HTML email - Error!<br>');

    Знаете, почему я кирилические письма отправляю в Windows-1251? Да потому что mail.ru не корректно принимает письма в utf-8, а в KOI-8 нет украинских букв(«і»,«ї»,«ґ»,«є»).

    Проверяем отправку. Мне на почту пришло таких вот два письма:

    Пришло письмо в текстовом формате Пришло письмо в HTML формате

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

    Комментарии

    22.11.2012 09:51:36
    Avatar of ВасяВася
    Спасибо за статью. Всё работает.
    24.07.2013 12:02:43
    Avatar of ДмитрийДмитрий
    Напишите пожалуйста про то как правильно отправлять почту чтобы она в гмэйле не в спам падала)
    25.07.2013 02:22:02
    Avatar of КонсервКонсерв
    Спам-фильтр Gmail (да и не только gmail) зависит от многих параметров.

    В первую очередь - это контент. Если тема письма - "Увеличь *** за 3 дня!", то оно почти наверняка попадёт в спам. Текст тоже имеет значение. Исходя из моего опыта, массовые рассылки ни к чему хорошему не приводят. Лучше чтобы письма отправлялись не все сразу, а через определённый промежуток времени (например, 1 письмо в минуту) да и контент хоть немного отличался.

    Далее - статистика рассылок с почтового сервера. Если с вашего сервера (имеет значение IP-адрес и доменное имя) регулярно отправляется спам, то он попадает в "чёрный список". На многих хостингах используется один или несколько почтовых серверов для всех сайтов, так что спам может отправлять ваш "сосед", а санкции понесут все. Обычно хостинги банят за спам. Можно сменить хостинг. Если вам надо 100% решение - закажите VDS или VPS и поднимите свой почтовый сервер.

    Ещё один фактор (довольно важный) - действия пользователей. Если хотя бы несколько адресатов с похожими письмами (например, в случае рассылки) нажали кнопку "это спам", то остальные письма рассылки (с похожим текстом) тоже попадают в спам. Желательно чтобы письма рассылки были более-менее уникальными (например, если вам надо отправить список новых статей на сайте за неделю, то можно отправлять не весь список, а ссылки только на те статьи, которые по тематике подходят данному пользователю).

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

    Если коротко, то рецепт один: если хотите, чтобы письма не попадали в папку "Спам", не пишите спам! :-)
    26.08.2013 05:53:25
    Avatar of mindnomindmindnomind
    Спасибо, добрый человек!
    16.12.2014 02:15:32
    Avatar of ЕвгенийЕвгений
    Спасибо огромное. Письма отправлял на два ящика, заказчику и себе. В ящик pop3 приходило в нормальном виде, в ящик для заказов, он подключен по imap, валились кракозябры. Все заработало как надо.
    19.08.2015 05:38:07
    Avatar of КонсервКонсерв
    @Евгений
    Пожалуйста :-)
    16.03.2018 09:43:47
    Avatar of JulieTapJulieTap
    День добрый.
    Спасибо за ресурс.
    08.08.2018 06:44:48
    Avatar of DarrenspeteDarrenspete
    13.08.2018 11:19:24
    Avatar of KulventKulvent
    Lump armpit brings discomfort, pulls. to Postpone trip in the hospital should not. Formation under the muscle cavity may become dangerous disease. However most often it is consequences regular use antiperspirants, violation rules personal hygiene, increased sweating. Inflammation triggers a close clothing, alien razor, the virus.
    <a href=http://armpit.info/how-much-should-you-worry-about-painful-lump-under-armpit>painful lump under armpit</a>
    Discomfort under the arm, redness, lump getting warm? This is the abscess that should cut, then drink medications. First treat lotions, antibacterial drugs. If the process switched to second stage, need surgery.
    16.08.2018 11:31:31
    Avatar of GlushkovAvtoGlushkovAvto
    Captcha Обновить
    Go Top