Новая версия класса SendMailSmtpClass. Отправка файлов через smtp с авторизацией по протоколу SSL на php

Новая версия класса SendMailSmtpClass

Больше четырех лет назад, я написал для своих нужд небольшой класс, для отправки писем через smtp. Это была первая версия SendMailSmtpClass. Через несколько месяцев после публикации класса и статьи о нем, на блоге прилично увеличилась посещаемость, и почти все поисковые запросы, так или иначе, были на тему отправки писем через smtp. Спустя еще 8-9 месяцев я немного дописал класс, теперь он смог отправлять письме через smtp с возможностью авторизации по ssl. Продолжение темы также стало быстро популярно среди посетителей сайта. И даже спустя 4 года темя не теряет своей актуальности, о чем может свидетельствовать десятки комментарием под статьями. А также, если верить метрике, то за последний месяц эти две статьи прочитало больше двух тысяч человек.
Выходит, что тема нужная и популярность ее не угасает. Но, судя по комментариям и письмам с вопросами, которые мне приходят на почту, то класс имеет свои недостатки. Самым большим, из которых является не удобная отправка файлов. Поэтому я решил немного обновить класс SendMailSmtpClass и добавить в него несколько улучшений.

Обновленный класс SendMailSmtpClass. Версия 1.1

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

Небольшие, но полезные обновления в SendMailSmtpClass

В первую очередь была немного переделана сама отправка письма, а именно приветственный запрос к smtp-серверам. Некоторые сервера не всегда отвечают на команду HELO, поэтому теперь в приветствии сначала отправляется EHLO. Если на EHLO нет ответа, то уже только тогда происходит отправка HELO. Надеюсь, эти манипуляции уменьшат процент проблем с авторизацией на smtp серверах.
Вторая переделка упростила код вызова класса и отправки письма. Теперь не нужно самим описывать заголовки – это происходит автоматически.
Третье обновление, это возможность отправки письма сразу нескольким получателям. Для этого достаточно указать получателей через запятую.
Ниже приведен код обновленной отправки с помощью smtp яндекса:

require_once "SendMailSmtpClass.php"; // подключаем класс
$mailSMTP = new SendMailSmtpClass('zhenikipatov@yandex.ru', '***', 'ssl://smtp.yandex.ru', 465, "UTF-8");
// $mailSMTP = new SendMailSmtpClass('логин', 'пароль', 'хост', 'порт', 'кодировка письма');

// от кого
$from = array(
	"Евгений", // Имя отправителя
	"test@vk-book.ru" // почта отправителя
);
// кому
$to = 'admin@vk-book.ru, ipatov@mega-dev.ru';

// отправляем письмо
$result =  $mailSMTP->send($to, 'Тема письма', 'Текст письма', $from); 
// $result =  $mailSMTP->send('Кому письмо', 'Тема письма', 'Текст письма', 'Отправитель письма');

if($result === true){
	echo "Done";
}else{
	echo "Error: " . $result;
}

Отправка писем в разной кодировке с помощью SendMailSmtpClass

Еще одно обновление класса – это возможность отправлять письма в разных кодировках. На данный момент можно использовать кодировки utf-8 и windows-1251. Это две самые популярные кодировки текста, с другими я не сталкивался при отправках почты. Если кому-то необходимы еще какие-то варианты кодировок, то пишите в комментарии, я постараюсь добавить их поддержку.
Для установки типа кодировки письма достаточно при инициализации класса указать нужную:

// будет использована кодировка utf-8
$mailSMTP = new SendMailSmtpClass('zhenikipatov@yandex.ru', '***', 'ssl://smtp.yandex.ru', 465, "UTF-8"); 

Отправка файлов через smtp с помощью SendMailSmtpClass

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

// добавляем файлы
$mailSMTP->addFile("test.jpg");
$mailSMTP->addFile("test2.jpg");
$mailSMTP->addFile("test3.txt");

Код класса и пример использования можно скачать из репозитория на github: ссылка.

Послесловие

Пишите свои комментарии по работе новой версии класса. Если есть какие-то пожелания или идеи, то также пишите о них.
Возможно, года через 4, выйдет новая версия класса :)


Рассказать друзьям:


Оценить:
(9 оценок, среднее: 4,89 из 5)

Новая версия класса SendMailSmtpClass. Отправка файлов через smtp с авторизацией по протоколу SSL на php: 33 комментария

  1. Hi there would you mind letting me know which webhost you’re using?
    I’ve loaded your blog in 3 completely different
    web browsers and I must say this blog loads a lot quicker then most.
    Can you recommend a good web hosting provider at a
    reasonable price? Many thanks, I appreciate it!

  2. Приветствую, а письма в «отправленных» на сервере сохраняются?
    И можно ли в скрытую копию адрес вставлять?

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

      1. Спасибо Вам.
        Попробую в файле класса «Bcc:» к заголовкам добавить, чтобы можно было скрытую копию указать.
        Через почтовую программу письма получаю, пишет To: undisclosed-recipients
        Видимо в заголовках «Кому» не прописано». Не на что не влияет, просто заметил особенность.

  3. $headers.= «To: «.$mailTo.»\r\n»;

    выдает ошибку:

    Notice: Undefined variable: mailTo in /…/SendMailSmtpClass/SendMailSmtpClass.php on line 200

    1. Это потому, что внутри метода getContentMail, не существует переменная $mailTo. Ее туда нужно передать сначала

        1. На блог заходят программисты разного уровня :) Для многих ООП или даже просто область видимости переменных — это сложно

  4. Добрый день!
    Спасибо за класс! Очень полезная штука.
    У меня есть проблемка с вложением файла. К письму при отправке прикрепляю файл jpg, а он приходит как текстовый, хотя расширение остается правильным. И в web интерфейсе ящика вложение не открывается…

    Какие могут быть причины такого поведения?

    1. Добрый день!
      Проверьте, как прикрепляете файл и существование самого файла. Если не получается, покажите код — только в комментарии его нужно обрамлять тегами pre, чтобы спецсимволы не порезались :)

    1. Приветствую! Для mail.ru критично, чтобы отправитель был указан тот же самый почтовый ящик, с которого происходит подключение по smtp, иначе не хочет слать.
      С яндексом проще — он шлет письмо с любым почтовым адресом отправителя, кроме mail.ru
      Проверьте, чтобы вот тут были указаны верные данные:

      // от кого
      $from = array(
          "Имя", // Имя отправителя
          "test@vk-book.ru" // почта отправителя. Для mail.ru нужно указать тот же ящик, что и в логине при инициализации класса. А для яндекса любой, кроме mail.ru
      );
      
      1. Да, все получилось. Спасибо. Через mail проверил по рекомендациям — работает. Но неинтересно в таком раскладе. Через yandex шлю на mail. Единственно,что не комильфо: в веб почте на mail.ru получаю такое: To: undisclosed-recipients (уже писали люди выше).

        1. Пояс на GMT+004 настроен) Хотя у меня время Московское. Честно говоря, я даже не обращал внимание 5 лет, пока Вы не сказали)

  5. Здравствуйте! Спасибо за Вашу программу.

    У меня не отправляется ничего, выдается ошибка:
    Error: .
    Добавил echo внутри класса:
    if(!$socket = @fsockopen($this->smtp_host, $this->smtp_port, $errorNumber, $errorDescription, 30)){
    echo $errorNumber.».».$errorDescription;
    throw new Exception($errorNumber.».».$errorDescription);
    }
    стала выходить ошибка
    Error: Autorization error

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

    require_once «SendMailSmtpClass.php»;
    $mailSMTP = new SendMailSmtpClass(‘box1@mail.ru’, ‘12345’, ‘ssl://smtp.mail.ru’, 465, «UTF-8»);

    $from = array(
    «Alex»,
    «box1@mail.ru»
    );
    $to = ‘box2@ya.ru’;

    $result = $mailSMTP->send($to, ‘Тема письма’, ‘Текст письма’, $from);

  6. Сменил сервис mail.ru на yandex.ru и все заработало. На mail.ru нужно привязывать почтовый ящик к домену, а потом еще прописывать настройки MX-записи у своего провайдера, но я не стал заморачиваться. И да, с яндекса на майл не отправляется, печалька.

  7. Добрый день, у меня одна и та же ошибка — ошибка авторизации когда подключаюсь ко гугл почте, Error of command sending: RCPT TO нашел строки в коде класса, но ничего не понял( помогитее

    1. Добрый день!
      Покажите код отправки и на какие ящики пытаетесь отправить письмо. А то так не понятно в чем дело. Такая ошибка появляется если сервер не может понять кому слать или отправить письмо адресату

      1. require_once "scripts/SendMailSmtpClass.php";
        
        $mailSMTP = new SendMailSmtpClass('vitalik.shumanskyi@gmail.com', 'xxx', 'ssl://smtp.gmail.com', 465, "utf-8");
        
        $from = array(
        	"Shumik_UA", // Имя отправителя
        	"vitalik.shumanskyi@gmail.com" // почта отправителя
        );
        
        $to = "$login";
        
        $result =  $mailSMTP->send($to, 'Підтвердження реєстрації', 'перейдіть по цій силці для того щоб підтвердити реєстрацію', $from); 
        
        if($result === true){
        	echo "Done";
        }else{
        	echo "Error: " . $result;
        }
        
        1. Попробуйте вместо переменной $to подставить какой-нибудь ящик для теста. И проверьте какие данные туда подставляются. В $login хранится почтовый ящик? не обязательно переменную оборачивать кавычками тут: $to = «$login»;

          1. ооо позор на мою голову) я вместо переменной $email поставил $login) огроомное спасибо) протестил что отправляю — сразу все понял, подставил емайл и все пошло)) еще раз спасибо за быструю поддержку и ваш способ отправки!)

  8. Добрый день! А что делать, если нет авторизации на сервере.
    К примеру, на работе сервер nsmail.work.ru без авторизации по 25 порту.
    Указываю $mailSMTP = new SendMailSmtpClass(«»,»», ‘nsmail.obespechenie-vniief.ru’, 25, «UTF-8»);
    Пишет: Ошибка: Autorization error
    Если в самом классе прописать public function __construct($smtp_username = «», $smtp_password = «», $smtp_host, $smtp_port = 25, $smtp_charset = «utf-8») — та же ошибка.
    Но если закомментировать строки авторизации
    fputs($socket, «AUTH LOGIN\r\n»);
    if (!$this->_parseServer($socket, «334»)) {
    fclose($socket);
    throw new Exception(‘Autorization error’);
    }

    fputs($socket, base64_encode($this->smtp_username) . «\r\n»);
    if (!$this->_parseServer($socket, «334»)) {
    fclose($socket);
    throw new Exception(‘Autorization error’);
    }

    fputs($socket, base64_encode($this->smtp_password) . «\r\n»);
    if (!$this->_parseServer($socket, «235»)) {
    fclose($socket);
    throw new Exception(‘Autorization error’);
    }
    То письмо отправляется. Я корректно настроила?

    1. Добрый день! Да, Вы все верно исправили в коде класса. В нем нет проверки на сервера без авторизации. И код, что Вы убрали, как раз и отвечает за обмен с smtp данными для авторизации — получается, что они на Вашем сервере не нужны

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*

code