Введите имя домена:
.ua .com.ua .in.ua .org.ua
.ru .com .net .org
Показать все домены

Как правильно настроить отправку почты с сайта?

Ответы на вопросы от компании «Украинский хостинг».

Настройка PHP mail – отправка почты скриптом

В целях борьбы со спам активностью и подделкой отправителя, многие хостинговые компании на данный момент устанавливают ограничения на отправку писем при помощи функции mail(), запрещающие отправку писем с почтовых ящиков, не созданных в аккаунте и явно не указанных в функции mail() в качестве отправителя, а так же не указанные в настройках PHP для параметра sendmail_path. В связи с этим, при настройке отправки почты с сайта необходимо необходимо учитывать данные ограничения. После создания почтового ящика требуется указать его в функции отправки писем в качестве отправителя, а так же в настройках PHP для параметра sendmail_path. Обычно значение параметра sendmail_path задается в файле php.ini или же через панель управления хостингом. После установки значения параметра sendmail_path необходимо проверить применились ли изменения. Это возможно сделать создав в корневой папке сайта файл с расширением php (для примера info.php) и указав в данном файле код:

<?php phpinfo(); ?>

Затем требуется открыть созданный файл в браузере, прописав в адресной строке браузера URL сайта и путь к файлу (для примера http://mysite.com.ua/info.php).

В открывшемся окне появится список настроек PHP, среди которых будет так же параметр sendmail_path:

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



<?php
/* Получатель (Указываем почтовый ящик получателя письма) */
$to = "poluchatel@gmail.com";

/* Тема (Указываем тему письма) */
$subject = "Тема";

/* Тема (Указываем текст письма) */
$message = 'Текст';

/* Заголовки */
$headers= "MIME-Version: 1.0\r\n";
$headers .= "Content-type: text/html; charset=iso-8859-1\r\n";

/* Отправитель (Указываем отправителя письма) */
$headers .= "From: info@mysite.com.ua\r\n";

/* Отправка */
mail($to, $subject, $message, $headers);
?>

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

Ниже указан рабочий скрипт отправки писем с сайта при помощи SMTP авторизации, в котором трется заменить данные подключения к почтовому ящику на собственные. Требуется создать два файла. Первый с названием SendMailSmtpClass.php , второй с любым требуемым названием, например mail.php

Код файла SendMailSmtpClass.php:


<?php
class SendMailSmtpClass {

    /**
    *
    * @var string $smtp_username - логин
    * @var string $smtp_password - пароль
    * @var string $smtp_host - хост
    * @var string $smtp_from - от кого
    * @var integer $smtp_port - порт
    * @var string $smtp_charset - кодировка
    *
    */
    public $smtp_username;
    public $smtp_password;
    public $smtp_host;
    public $smtp_from;
    public $smtp_port;
    public $smtp_charset;
	public $boundary;
    public $addFile = false;
    public $multipart;

    public function __construct($smtp_username, $smtp_password, $smtp_host, $smtp_port = 25, $smtp_charset = "utf-8") {
        $this->smtp_username = $smtp_username;
        $this->smtp_password = $smtp_password;
        $this->smtp_host = $smtp_host;
        $this->smtp_port = $smtp_port;
        $this->smtp_charset = $smtp_charset;

		// разделитель файлов
		$this->boundary = "--".md5(uniqid(time()));
		$this->multipart = "";
    }

    /**
    * Отправка письма
    *
    * @param string $mailTo - получатель письма
    * @param string $subject - тема письма
    * @param string $message - тело письма
    * @param string $smtp_from - отправитель. Массив с именем и e-mail
    *
    * @return bool|string В случаи отправки вернет true, иначе текст ошибки
	*
    */
    function send($mailTo, $subject, $message, $smtp_from) {
		// подготовка содержимого письма к отправке
		$contentMail = $this->getContentMail($subject, $message, $smtp_from,$mailTo);

        try {
            if(!$socket = @fsockopen($this->smtp_host, $this->smtp_port, $errorNumber, $errorDescription, 30)){
                throw new Exception($errorNumber.".".$errorDescription);
            }
            if (!$this->_parseServer($socket, "220")){
                throw new Exception('Connection error');
            }

			$server_name = $_SERVER["SERVER_NAME"];
            fputs($socket, "EHLO $server_name\r\n");
			if(!$this->_parseServer($socket, "250")){
				// если сервер не ответил на EHLO, то отправляем HELO
				fputs($socket, "HELO $server_name\r\n");
				if (!$this->_parseServer($socket, "250")) {
					fclose($socket);
					throw new Exception('Error of command sending: HELO');
				}
			}

            fputs($socket, "AUTH LOGIN\r\n");
            if (!$this->_parseServer($socket, "334")) {
                fclose($socket);
                throw new Exception('Autorization error 1');
            }

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

            fputs($socket, base64_encode($this->smtp_password) . "\r\n");
            if (!$this->_parseServer($socket, "235")) {
                fclose($socket);
                throw new Exception('Autorization error 3');
            }

            fputs($socket, "MAIL FROM: <".$this->smtp_username.">\r\n");
            if (!$this->_parseServer($socket, "250")) {
                fclose($socket);
                throw new Exception('Error of command sending: MAIL FROM');
            }

			$mailTo = str_replace(" ", "", $mailTo);
			$emails_to_array = explode(',', $mailTo);


			foreach($emails_to_array as $email) {
				fputs($socket, "RCPT TO: <{$mailTo}>\r\n");
				if (!$this->_parseServer($socket, "250")) {
					fclose($socket);
					throw new Exception('Error of command sending: RCPT TO');
				}
			}


            fputs($socket, "DATA\r\n");
            if (!$this->_parseServer($socket, "354")) {
                fclose($socket);
                throw new Exception('Error of command sending: DATA');
            }

            fputs($socket, $contentMail."\r\n.\r\n");
            if (!$this->_parseServer($socket, "250")) {
                fclose($socket);
                throw new Exception("E-mail didn't sent");
            }

            fputs($socket, "QUIT\r\n");
            fclose($socket);
        } catch (Exception $e) {
            return  $e->getMessage();
        }
        return true;
    }


	// добавление файла в письмо
	public function addFile($path){
		$file = @fopen($path, "rb");
		if(!$file) {
			throw new Exception("File `{$path}` didn't open");
		}
		$data = fread($file,  filesize( $path ) );
		fclose($file);
		$filename = basename($path);
		$multipart .=  "\r\n--{$this->boundary}\r\n";
		$multipart .= "Content-Type: application/octet-stream; name=\"$filename\"\r\n";
		$multipart .= "Content-Transfer-Encoding: base64\r\n";
		$multipart .= "Content-Disposition: attachment; filename=\"$filename\"\r\n";
		$multipart .= "\r\n";
		$multipart .= chunk_split(base64_encode($data));

		$this->multipart .= $multipart;
		$this->addFile = true;
	}

	// парсинг ответа сервера
    private function _parseServer($socket, $response) {
        while (@substr($responseServer, 3, 1) != ' ') {
            if (!($responseServer = fgets($socket, 256))) {
                return false;
            }
        }
        if (!(substr($responseServer, 0, 3) == $response)) {
            return false;
        }
        return true;
    }

	// подготовка содержимого письма
	private function getContentMail($subject, $message, $smtp_from,$mailTo){
		// если кодировка windows-1251, то перекодируем тему
		if( strtolower($this->smtp_charset) == "windows-1251" ){
			$subject = iconv('utf-8', 'windows-1251', $subject);
		}
        $contentMail = "Date: " . date("D, d M Y H:i:s") . " UT\r\n";
        $contentMail .= 'Subject: =?' . $this->smtp_charset . '?B?'  . base64_encode($subject) . "=?=\r\n";

		// заголовок письма
		$headers = "MIME-Version: 1.0\r\n";

		// кодировка письма
		if($this->addFile){
			// если есть файлы
			$headers .= "Content-Type: multipart/mixed; boundary=\"{$this->boundary}\"\r\n";
		}else{
			$headers .= "Content-type: text/html; charset={$this->smtp_charset}\r\n";
		}
		$headers .= "From: {$smtp_from[0]} <{$smtp_from[1]}>\r\n"; // от кого письмо
         $headers.= "To: ".$mailTo."\r\n";
        $contentMail .= $headers . "\r\n";

		if($this->addFile){
			// если есть файлы
			$multipart  = "--{$this->boundary}\r\n";
			$multipart .= "Content-Type: text/html; charset=utf-8\r\n";
			$multipart .= "Content-Transfer-Encoding: base64\r\n";
			$multipart .= "\r\n";
			$multipart .= chunk_split(base64_encode($message));

			// файлы
			$multipart .= $this->multipart;
			$multipart .= "\r\n--{$this->boundary}--\r\n";

			$contentMail .= $multipart;
		}else{
			$contentMail .= $message ."\r\n";
		}

		// если кодировка windows-1251, то все письмо перекодируем
		if( strtolower($this->smtp_charset) == "windows-1251" ){
			$contentMail = iconv('utf-8', 'windows-1251', $contentMail);
		}

		return $contentMail;
	}

}
?>

Код файла mail.php:


<?php
/* Подключение класса */
require_once "SendMailSmtpClass.php";
	  
/* Подключение к SMTP серверу (Указываем почтовый ящик отправителя, пароль, SMTP сервер, порт и кодировку) */
$mailSMTP = new SendMailSmtpClass('info@mysite.com.ua', 'Password', 'mail.mysite.com.ua ', 25, "UTF-8");

/* Отправитель (Указываем имя отправителя и почтовый ящик отправителя) */
$from = array("Имя отправителя", "info@mysite.com.ua");

/* Отправка (Указываем почтовый ящик получателя, тему письмо и текст письма) */
$result =  $mailSMTP->send('poluchatel@gmail.com', 'Тема', 'Текст', $from);
?>

См.также:

Будь ласка, виберіть мову сайту за промовчанням: