Это архивная статья. Блог закрыт.

← на главную

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

Статья написана очень давно — 06.06.2010

В этой статье хочу поведать Вам о том, как отправлять почту с вложениями стандартными средствами PHP, не прибегая к PEAR и подобным библиотекам.

Начнем с азов. Отправка почты в php выполняется с помощью функции mail:

bool mail ( string $to, string $subject, string $message [, string $additional_headers [, string $additional_parameters]] )
  to      - адрес получателя
  subject - тема письма
  message - текст письма
Далее слудуют необязательные параметры:
  additional_headers    - дополнительные заголовки
  additional_parameters - дополнительные параметры командной строки
Возвращаемое значение:
  true  - письмо принято к доставке
  false - письмо не принято к доставке

В простейшем виде это выглядит так:

<?php
 if (mail('test@example.com', 'Письмо из скрипта', 'Привет, Василий! Как дела?')){
  echo 'Письмо успешно отправлено!';
 }else{
  echo 'При отправке письма возникла ошибка';
 }
?>

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

Теперь разберёмся с дополнительными заголовками. Что вообще такое, заголовок письма? Это, согласно стандарту RFC-822, одна из частей электронного письма. То есть, письмо состоит из заголовков и тела (также и из "конверта", но это нам сейчас не нужно). Заголовок всегда находится перед телом и отделен от него пустой строкой. Заголовок состоит из имени и содержания, разделённых двоеточием. Между собой заголовки разделяются так: каждый заголовок начинается с новой строки. Но, лучше смотреть на примере:

Date: Fri, 4 Jun 2010 16:12:00
From: sales@example.com
To: ivan@example.com
Reply-to: sales@example.com
Subject: Ваш заказ принят
X-Mailer: php script

Следовательно, чтобы, к примеру, установить произвольную дату письма, или установить адрес отправителя, необходимо указать заголовки (по умолчанию, дата задаётся текущая, а тема устанавливается во втором параметре)

<?php
 if (mail('test@example.com', 'Письмо из скрипта', 'Привет Василий, как дела?', 'From: ivan@example.com')){
  echo 'Письмо успешно отправлено!';
 }else{
  echo 'При отправке письма возникла ошибка';
 }
?>

Отправка письма в HTML-формате

Большинству задач вышеприведённого скрипта отправки mail`ов хватает, но мы пойдём дальше, и научимся отправлять письма в HTML-формате. В этом также нет ничего сложного:

<?php
 if (mail('test@example.com',
                 'Письмо из скрипта',
                 '<html><head><title>Вася, привет</title></head><body bgcolor="#feeffe"><font color="blue">Привет Василий, как дела?</font><br /><font color="green">Я умею отправлять письма с помощью php! И скоро научусь отправлять письма с помощью php с вложениями! Это будет круто!</font></body></html>',
                 "From: ivan@example.com\r\n
		  Content-type: text/html; charset=utf-8\r\n
                  X-Mailer: PHP mail script"
                ))
 {
  echo 'Письмо успешно отправлено!';
 }else{
  echo 'При отправке письма возникла ошибка';
 }
?>

Обратите внимание! После каждого заголовка стоит конструкция \r\n — это так обозначается перенос строки. А тот перенос, что вы видите — это обычное выравнивание, дабы удобно было читать код. Т.е. смело можно написать так:

 ...mail('test@example.com', 'Письмо из скрипта', '(аштиэмэль...)', "From: ivan@example.com\r\nContent-type: text/html; charset=utf-8\r\nX-Mailer: PHP mail script")...

И ещё обратите внимание на то, что escape-последовательности (а именно так называются конструкции вида \r\n) работают только с двойными кавычками!
Что же нового в этом скрипте? Ну, во-первых, мы в заголовках указали тип содержимого (HTML) и кодировку. Во-вторых, просто в теле написали нужный нам html-код. Всё просто!

Отправка писем с вложениями

Вот мы вплотную подошли к отправке писем на php с вложениями.

<?php
 $un   = strtoupper(uniqid(time()));
 $file = file_get_contents('file.zip');
 if (mail('test@example.com',
                 'Письмо из скрипта',
                 //тело                 
                 "------------".$un."\r\n\r\n
                  Content-Type:text/plain; charset=utf-8\r\n
                  Content-Transfer-Encoding: 8bit\r\n\r\n
                  Привет Василий, посмотри вложение\r\n\r\n
                  ------------".$un."\r\n\r\n
                  Content-Type: application/octet-stream;name=\"file.zip\"\r\n\r\n
                  Content-Transfer-Encoding:base64\r\n
                  Content-Disposition:attachment;filename="file.zip"\r\n\r\n
                  ".chunk_split(base64_encode($file))."\r\n
                  ",
                  //заголовки
                 "From: ivan@example.com\r\n
                  MIME-Version: 1.0\r\n
                  Content-Type: multipart/alternative;boundary=\"----------".$un."\"\r\n
		  "
                ))
 {
  echo 'Письмо успешно отправлено!';
 }else{
  echo 'При отправке письма возникла ошибка';
 }
?>

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

Но как происходит отправка? В заголовках мы указываем тип содержимого и наш уникальный разделитель (Content-Type: multipart/alternative;boundary=\"----------".$un."\"). А в теле письма, разделяя разделителем, пишем сначала текст, потом вложенный файл:

"------------".$un."\r\n\r\n
  Content-Type:text/plain; charset=utf-8\r\n
  Content-Transfer-Encoding: 8bit\r\n\r\n
  Привет Василий, посмотри вложение\r\n\r\n

  ------------".$un."\r\n
  Content-Type: application/octet-stream;name=\"file.zip\"\r\n\r\n
  Content-Transfer-Encoding:base64\r\n
  Content-Disposition:attachment;filename=\"file.zip\"\r\n\r\n
  ".chunk_split(base64_encode($file))

Пишем, естественно, с указанием типа содержимого (Content-Type) и типа конвертации (Content-Transfer-Encoding).
chunk_split(base64_encode($file)) — это и есть вложение нашего файла (помните, мы в переменную $file внесли содержимое?), предварительно его конвертировав в base64

Готовая функция отправки почты с вложением

Если терпеливый читатель дочитал до этого места, то вот универсальная функция отправки почты с вложением:

function KMail($to, $from, $subj, $text, $files = null, $isHTML = false){
 $boundary = "------------".strtoupper(md5(uniqid(rand())));
 $headers  = "From: ".$from."\r\n
              X-Mailer: koz1024.net\r\n
              MIME-Version: 1.0\r\n
              Content-Type: multipart/alternative;boundary=\"$boundary\"\r\n\r\n
             ";
 if (!$isHTML){
  $type = 'text/plain';
 }else{
  $type = 'text/html';
 }
   $body =  $boundary."\r\n\r\n
            Content-Type:".$type."; charset=utf-8\r\n
            Content-Transfer-Encoding: 8bit\r\n\r\n
            ".$text."\r\n\r\n";
 if ((is_array($files))&&(!empty($files))){
    foreach($files as $filename => $filecontent){
       $body .= $boundary."\r\n
                Content-Type: application/octet-stream;name=\"".$filename."\"\r\n
                Content-Transfer-Encoding:base64\r\n
                Content-Disposition:attachment;filename=\"".$filename."\"\r\n\r\n
                ".chunk_split(base64_encode($filecontent));
    }
 }
 return mail($to, $subj, $body, $headers);
}

Использование:

  $files = array('archive.zip' => file_get_contents('archive.zip'), 'myphoto.png' => file_get_contents('myfoto.png'));
  if (KMail('test@example.com', 'ivan@example.com', 'проба пера', 'Привет, высылаю файлы...', $files, false)){
   echo 'Mail Отправлен';
  }else{
   echo 'Произошла ошибка';
  }
//или так
  $html = "(HTML код письма)";
  if (KMail('test@example.com', 'ivan@example.com', 'проба пера', $html, null, true)){
   echo 'Mail Отправлен';
  }else{
   echo 'Произошла ошибка';
  }

С полученными знаниями, Вы без труда разберетесь в работе этой функции. Надеюсь, она Вам пригодится!

Отправка письма в HTML формате с картинками

Хотел написать этот раздел сразу после "Отправки письма в HTML-формате", и это было бы логично. Но. Раздел бы получился очень громоздким, а пользуясь функцией, которую я описал выше, можно легко передавать письма в формате HTML да ещё и с картинками. Скажу лишь о том, что сами картинки должны являтся частью html кода, а вместо ссылок на них — использоваться cid - идентификаторы

Вот мы и разобрали, как с помощью простого php отправлять e-mail`ы, отправлять в HTML-формате, отправлять с вложениями. Удачи!

Комментарии удалены

© koz1024 2010, 2019