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

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

Проблемы с кодировкой при отправке email писем посредством php мы уже разобрали в предыдущей части нашей статьи. Давайте разберёмся с оставшимися вопросами.

Итак, на повестке дня: использование вложений и вставка изображения в тело письма.

Наверняка многим на почту приходили красивые письма с вёрсткой и картинками. А отправляя письма собственноручно, приходит некрасивый текст. В данной статье мы научимся отправлять письма с красивой версткой и картинками, что часто бывает необходимо при отправке рассылок.

Если вы когда-нибудь сталкивались с отправкой таких писем, то, скорее всего у вас часто возникали следующие проблемы:

  • вложенный файл не открывается или открывается неправильно
  • не показывается текст
  • картинку можно скачать, но она не вставляется в тело письма.

Давайте, попробуем со всем этим разобраться.

Для отправки писем с вложениями используется специальный формат, который называется multipart. В заголовках (headers) он указывается как Content-type: multipart/mixed; boundary=... При этом тело письма состоит из кусочков (каждый кусочек — это часть письма, текст или вложение), которые разделяются значением boundary. Каждый кусочек имеет свои заголовки (конечно же Content-type, ну и другие).

Если кусочку ещё и задать Content-ID, то его можно вставлять в HTML (ссылка при этом будет выглядеть как «CID:<значение Content-ID>»).

Написаный ранее класс для работы с почтой я модифицировал под отправку multipart сообщений:

  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.   //Части сообщения - текст и т.п.
  10.   private $EOL;
  11.   private $parts=array();
  12.   //Конструктор
  13.   function __construct(){
  14.     $this->EOL=CHR(13).CHR(10);
  15.     }
  16.   //Функция, прикрепляющая файл
  17.   function attachment($content_type,$name,$fn,$content_id=''){
  18.     //Read data from the file...
  19.     $fp=fopen($fn,'rb');
  20.     if(!$fp)return false;
  21.     $str=fread($fp,filesize($fn));
  22.     fclose($fp);
  23.     $msg['attachment']=true;
  24.     $msg['content_type']=$content_type;
  25.     $msg['content_id']=$content_id; //Для вставки в тело письма
  26.     $msg['data']=$str;
  27.     $msg['name']=$name;
  28.     $msg['send_charset']='';
  29.     $msg['transfer_encoding']='base64';
  30.     array_push($this->parts,$msg);
  31.     }
  32.   //Функция, добавляющая тело сообщения
  33.   function body($content_type,$str){
  34.     $msg['attachment']=false;
  35.     $msg['content_type']=$content_type;
  36.     $msg['content_id']='';
  37.     $msg['data']=$str;
  38.     $msg['name']='';
  39.     $msg['send_charset']=$this->send_charset;
  40.     $msg['transfer_encoding']='8bit';//'quoted-printable';
  41.     array_push($this->parts,$msg);
  42.     }
  43.   //Функция для отправки multipart сообщения (с вложениями)
  44.   function send_multipart(){
  45.     $dc=$this->data_charset;
  46.     $sc=$this->send_charset;
  47.     $EOL=$this->EOL;
  48.     $boundary='a'.sha1(uniqid(time()));//любая строка, которой не будет в потоке данных.
  49.     //Encode some fields
  50.     $enc_to=mime_header_encode($this->to_name,$dc,$sc).' <'.$this->to_email.'>';
  51.     $enc_subject=mime_header_encode($this->subject,$dc,$sc);
  52.     if(!empty($this->from_email))
  53.        $enc_from=mime_header_encode($this->from_name, $dc, $sc).' <'.$this->from_email.'>';else
  54.        $enc_from='';
  55.     //Process data...
  56.     $multipart='';
  57.     for($i=0;$i<count($this->parts);$i++){
  58.       $ctype=$this->parts[$i]['content_type'];
  59.       $cname=$this->parts[$i]['name'];
  60.       $ccharset=$this->parts[$i]['send_charset'];
  61.       $ctenc=$this->parts[$i]['transfer_encoding'];
  62.       $cid=$this->parts[$i]['content_id'];
  63.       //Put file into multipart
  64.       $multipart.='--'.$boundary.$EOL;
  65.       $multipart.='Content-Type: '.$ctype.
  66.         (empty($ccharset)?'':'; charset='.$ccharset).
  67.         (empty($cname)?'':'; name='.$cname).$EOL;
  68.       if(!empty($cid))
  69.         $multipart.='Content-ID: <'.$cid.'>'.$EOL;
  70.       $multipart.='Content-Transfer-Encoding: '.$ctenc.$EOL;
  71.       //Different encodings
  72.       if($ctenc=='8bit'){//quoted-printable
  73.         $enc_body=$dc==$ccharset?
  74.           $this->parts[$i]['data']:
  75.           iconv($dc,$ccharset.'//IGNORE',$this->parts[$i]['data']);
  76.         $multipart.=$EOL.$enc_body.$EOL;
  77.         }else
  78.       if($ctenc=='base64'){
  79.         $multipart.=$EOL.chunk_split(base64_encode($this->parts[$i]['data']),76,$EOL).$EOL;
  80.         };
  81.       }
  82.     $multipart.='--'.$boundary.'--'.$EOL;
  83.     //
  84.     $headers='';
  85.     $headers.='Mime-Version: 1.0'.$EOL;
  86.     $headers.='Content-type: multipart/mixed; boundary='.$boundary.$EOL;
  87.     if(!empty($enc_from))
  88.        $headers.='From: '.$enc_from.$EOL;
  89.     //Send email
  90.     return mail($enc_to,$enc_subject,$multipart,$headers);
  91.     }
  92.   //Функция для отправки обычного сообщения
  93.   function send_single(){
  94.     //Get some global variables...
  95.     $dc=$this->data_charset;
  96.     $sc=$this->send_charset;
  97.     $EOL=$this->EOL;
  98.     $body=$this->parts[0]['data'];
  99.     $ctype=$this->parts[0]['content_type'];
  100.     $ccharset=$this->parts[0]['send_charset'];
  101.     //Encode some fields
  102.     $enc_to=mime_header_encode($this->to_name,$dc,$sc).' <'.$this->to_email.'>';
  103.     $enc_subject=mime_header_encode($this->subject,$dc,$sc);
  104.     if(!empty($this->from_email))
  105.        $enc_from=mime_header_encode($this->from_name, $dc, $sc).' <'.$this->from_email.'>';else
  106.        $enc_from='';
  107.     //Encode Body
  108.     $enc_body=$dc==$ccharset?$body:iconv($dc,$ccharset.'//IGNORE',$body);
  109.     //Form headers
  110.     $headers='';
  111.     $headers.='Mime-Version: 1.0'.$EOL;
  112.     $headers.='Content-type: '.$ctype.'; charset='.$ccharset.$EOL;
  113.     if(!empty($enc_from))
  114.        $headers.='From: '.$enc_from.$EOL;
  115.     //Send email
  116.     return mail($enc_to,$enc_subject,$enc_body,$headers);
  117.     }
  118.   function send(){
  119.     if(count($this->parts)==1) return $this->send_single(); else
  120.     if(count($this->parts)>1) return $this->send_multipart(); else
  121.       return false;
  122.     }
  123.   }

Тут функция send() проверяет количество «кусочков». Если «кусочек» один, то отправляет его как текст. Ведь multipart нам не нужен, если мы отправляем только текст.

Функции attachment() и body() прикрепляют текст или вложение. Принцип их работы, я думаю, понятен.

Отправка писем с вложениями не представляет сложности. Тут я прикрепляю картинку и zip-архив:

  1.   require_once(dirname(__FILE__).'/email_api.php');
  2.   echo('Trying to send emails...<br>');
  3.   //HTML email
  4.   echo('Email with attachment - sending...<br>');
  5.   $email=new TEmail;
  6.   $email->from_email='noreply@konservs.com';
  7.   $email->from_name='От "Записок Консерваторов"';
  8.   $email->to_email='*********';
  9.   $email->subject='Тема (ІЇҐЭЄ іїґэє)';
  10.   $email->body('text/html','Письмо в HTML с вложениями.<br>'.
  11.     'Картинка:'.
  12.     '<img src="cid:cid1">'.
  13.     '<h1>Header 1 (Заголовок 1)</h1>'.
  14.     '<h2>Header 2 (Заголовок 2)</h2>'.
  15.     '<h3>Header 3 (Заголовок 3)</h3>'.
  16.     '<h4>Header 4 (Заголовок 4)</h4>'.
  17.     '<h5>Header 5 (Заголовок 5)</h5>'.
  18.     'Тест: ІЇҐЭЄ іїґэє');
  19.   $DS=DIRECTORY_SEPARATOR;
  20.   $email->attachment('image/jpeg','logo.jpg',dirname(__FILE__).$DS.'files'.$DS.'test.jpg','cid1');
  21.   $email->attachment('application/octet-stream','test.zip',dirname(__FILE__).$DS.'files'.$DS.'test.zip');
  22.   if($email->send())
  23.     echo('Email with attachment - OK.<br>'); else
  24.     echo('Email with attachment - Error!<br>');

Пример письма, которое пришло мне.

Письмо с вложением и картинкой

Поздравляем! Вы научились отправлять письма с вложениями.

Комментарии

09.12.2014 05:37:54
Avatar of МиколаМикола
Постійно користуюся цим класом!
Спасибі!
26.12.2016 06:52:44
Avatar of МиколаМикола
ти не повіриш, але все ще користуюся)
20.09.2017 05:48:02
Avatar of
21.09.2017 04:03:52
Avatar of rElenaFutrElenaFut
Работа в интернете
02.10.2017 04:24:10
Avatar of AngelopefAngelopef
Do you feel like you have tried everything possible in order to lose weight? You are not alone--many people have the same problem. The following article is designed to give you tips that you may not have even known existed. By following these tips, you will reach your weight loss goal in no time.
27.10.2017 11:32:52
Avatar of EkaterinaEkaterina
88123177279 Екатерина Алексеевна (домашний)
10.11.2017 07:35:51
Avatar of AugustDoxAugustDox
WhatsUp: +380734849435
Email: maksym@shemetmask3d.com
11.11.2017 07:23:09
Avatar of OscarerypeOscarerype
Вам yужны отзывы и коментарии о Вашей продукции и услугах? Хотите сместить негативные отзывы и комментарии вниз?
Без предоплаты!!!.Вы заплатите только после того как Вам понравится и будут опубликованны комментарии и отзывы!!!
Самые низкие цены!!!от 20 рублей за отзыв от 5 рублей за комментарий.
Все без посредников - общение и оплата напрямую с авторами!
Заинтерисовало? Подробнее здесь!!! https://goo.gl/N6JiUE
18.11.2017 02:05:27
Avatar of BrandonFropyBrandonFropy
Предлагаем Вам уменьшить размер изображений на Вашем сайте, это ускорит скорость загрузки Вашего сайта.
Большинство посетителей пользуются для просмотра сайтов мобильными телефонами/смартфонами.
Чтобы сайт загружался быстро, не вис и не тормозил -необходимо сжатие картинок.
Подробнее здесь https://goo.gl/sj4UyQ
*Для небольших сайтов оптимизация бесплатно- до 10 мегабайт
Если Вы превысили лимит -воспользуйтесь скидочным купоном
- введите 3G92NuI2g9CYi_RcnbZ9dSZ_mWlQf5ER и получите скидку**
**Действует только при регистрации по ссылке!

P.S Если мы нарушили Ваше спокойствие и Вы не нуждаетесь в наших услугах-приносим Вам свои извенения!
Captcha Обновить
Go Top