Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В. Социальная инженерия и социальные хакеры. Авторы: Кузнецов М.В., Симдянов И.В. PHP 5/6. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. MySQL на примерах. Авторы: Кузнецов М.В., Симдянов И.В. MySQL 5. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум PHP

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Content-type: text/alternative
 
 автор: Николай2357   (10.09.2009 в 00:44)   письмо автору
 
 

Здравствуйте.
При генерации электронного письма никак не могу построить дерево такого плана:
три части тела: текст, html и файл. Текст и html должны быть альтернативными, файл прикреплен. То есть я понимаю что должно быть примерно так:
Content-type: multipart/mixed 
                Content-type: multipart/alternative 
                        Content-type: text/plain                     
                        Content-type: text/html 
                Content-type: image/jpeg

но вот с разделителями запутался. Если так:

Content-type: multipart/mixed boundary="boundary1"
..............boundary1........................
                Content-type: multipart/alternative boundary="boundary2"
               .............boundary2........................
                        Content-type: text/plain  
               .............boundary2........................                  
                        Content-type: text/html 

алтернатива не работает... А мне еще файл надо приторочить сюда.
Подскажите, кто с почтой на ты.
Спасибо.

  Ответить  
 
 автор: Trianon   (10.09.2009 в 00:59)   письмо автору
 
   для: Николай2357   (10.09.2009 в 00:44)
 

Нарисованое в первом квадратике имеет некоторый строгий смысл,
во втором - никакого.
Либо отступы - либо разделители.
И если разделители, то согласно RFC-2045 (2049 тоже можно глянуть)

  Ответить  
 
 автор: Николай2357   (10.09.2009 в 01:16)   письмо автору
 
   для: Trianon   (10.09.2009 в 00:59)
 

Это просто я так неудачно дерево пытался изобразить. Вообще то результат выглядет так:
X-Sendmail-Cmdline: sendmail.pl -t -i -f= utf-8 b ZW1haWxAeWFuZGV4LnJ1 =
To: =?utf-8?b?ZW1haWxAbWFpbC5ydQ==?=
Subject: =?utf-8?b?0KLQsNCx0LUg0L/QsNC60LXRgg==?=
Content-type: multipart/mixed; boundary="==46122d47fcba87789f3188812e78b036" 
From: <=?utf-8?b?ZW1haWxAeWFuZGV4LnJ1?=>
MIME-Version: 1.0
Date: Thu, 10 Sep 2009 05:10:13 +0400


--==46122d47fcba87789f3188812e78b036
Content-type: text/alternative;  boundary="==52803978d55bb25cb00b8397b03b4f68" 
--==52803978d55bb25cb00b8397b03b4f68
Content-type: text/plain; charset="utf-8"
Content-Transfer-Encoding: base64

0JLQvtGCINGC0LDQutC+0LUg0LLQvtGCINC/0LjRgdGM0LzQvg==

--==52803978d55bb25cb00b8397b03b4f68
Content-type: text/html; charset="utf-8"
Content-Transfer-Encoding: base64

PGgxIHN0eWxlPSJjb2xvcjpibHVlIj7QktC+0YIg0YLQsNC60L7QtSDQstC+0YIg0L/QuNGB0YzQ
vNC+PC9oMT4=

  Ответить  
 
 автор: Николай2357   (10.09.2009 в 09:18)   письмо автору
 
   для: Николай2357   (10.09.2009 в 01:16)
 

Нету почтальёнов? )))
Да что ж я не так делаю то... вроде все просто как дважды два. Вот так естественно работает:
X-Sendmail-Cmdline: sendmail.pl -t -i -f= utf-8 b ZW1haWxAeWFuZGV4LnJ1 =
To: =?utf-8?b?ZW1haWxAbWFpbC5ydQ==?=
Subject: =?utf-8?b?0KLQsNCx0LUg0L/QsNC60LXRgg==?=
Content-type: multipart/alternative; boundary="==boundary1" 
From: <=?utf-8?b?ZW1haWxAeWFuZGV4LnJ1?=>
MIME-Version: 1.0
Date: Thu, 10 Sep 2009 01:00:27 +0400


--==boundary1
Content-type: text/plain; charset="utf-8"
Content-Transfer-Encoding: base64

0JLQvtGCINGC0LDQutC+0LUg0LLQvtGCINC/0LjRgdGM0LzQvg==

--==boundary1
Content-type: text/html; charset="utf-8"
Content-Transfer-Encoding: base64

PGgxIHN0eWxlPSJjb2xvcjpibHVlIj7QktC+0YIg0YLQsNC60L7QtSDQstC+0YIg0L/QuNGB0YzQ
vNC+PC9oMT4=

А вот так не хочет:
X-Sendmail-Cmdline: sendmail.pl -t -i -f= utf-8 b ZW1haWxAeWFuZGV4LnJ1 =
To: =?utf-8?b?ZW1haWxAbWFpbC5ydQ==?=
Subject: =?utf-8?b?0KLQsNCx0LUg0L/QsNC60LXRgg==?=
Content-type: multipart/mixed; boundary="==boundary1" 
From: <=?utf-8?b?ZW1haWxAeWFuZGV4LnJ1?=>
MIME-Version: 1.0
Date: Thu, 10 Sep 2009 01:00:27 +0400


--==boundary1
Content-type: multipart/alternative; boundary="==boundary2" 
--==boundary2
Content-type: text/plain; charset="utf-8"
Content-Transfer-Encoding: base64

0JLQvtGCINGC0LDQutC+0LUg0LLQvtGCINC/0LjRgdGM0LzQvg==

--==boundary2
Content-type: text/html; charset="utf-8"
Content-Transfer-Encoding: base64

PGgxIHN0eWxlPSJjb2xvcjpibHVlIj7QktC+0YIg0YLQsNC60L7QtSDQstC+0YIg0L/QuNGB0YzQ
vNC+PC9oMT4=
Вроде бы всё по науке... Чего ж я недосмотрел...

  Ответить  
 
 автор: Trianon   (10.09.2009 в 10:58)   письмо автору
 
   для: Николай2357   (10.09.2009 в 09:18)
 


To: name@domain
From: name@domain
MIME-Version: 1.0
Date: Thu, 10 Sep 2009 01:00:27 +0400
Subject: subject
Content-type: multipart/mixed; boundary="#1"

dummy  text part 1

--#1
Content-type: multipart/alternative; boundary="#2"

dummy  text part 2

--#2
Content-type: text/plain; charset="utf-8"
Content-Transfer-Encoding: base64

0JLQvtGCINGC0LDQutC+0LUg0LLQvtGCINC/0LjRgdGM0LzQvg==

--#2
Content-type: text/html; charset="utf-8"
Content-Transfer-Encoding: base64

PGgxIHN0eWxlPSJjb2xvcjpibHVlIj7QktC+0YIg0YLQsNC60L7QtSDQstC+0YIg0L/QuNGB0YzQ
vNC+PC9oMT4=

--#2--
--#1
Content-type: application/octet-stream; name="file.ext"
Content-disposition: attachment; filename="file.ext"
Content-Transfer-Encoding: base64

PGgxIHN0eWxlPSJjb2xvcjpibHVlIj7QktC+0YIg0YLQsNC60L7QtSDQstC+0YIg0L/QuNGB0YzQ
PGgxIHN0eWxlPSJjb2xvcjpibHVlIj7QktC+0YIg0YLQsNC60L7QtSDQstC+0YIg0L/QuNGB0YzQ
PGgxIHN0eWxlPSJjb2xvcjpibHVlIj7QktC+0YIg0YLQsNC60L7QtSDQstC+0YIg0L/QuNGB0YzQ
vNC+PC9oMT4=

--#1--

  Ответить  
 
 автор: Trianon   (10.09.2009 в 10:46)   письмо автору
 
   для: Николай2357   (10.09.2009 в 01:16)
 

Для любой целого либо части: Заголовок этого целого/части должен отделяться от тела этого целого/части пустой строкой.

  Ответить  
 
 автор: Николай2357   (10.09.2009 в 10:59)   письмо автору
 
   для: Trianon   (10.09.2009 в 10:46)
 

О, огромное спасибо

  Ответить  
 
 автор: Trianon   (10.09.2009 в 11:00)   письмо автору
 
   для: Николай2357   (10.09.2009 в 10:59)
 

>Это просто издержки всемогущего метода тыка.
Пока Вы будете тыкать, а не читать RFC (или хотя бы смотреть результат работы почтовых клиентов) так оно всё и будет.

  Ответить  
 
 автор: Николай2357   (10.09.2009 в 14:40)   письмо автору
 
   для: Trianon   (10.09.2009 в 11:00)
 

Успели прочитать))) Да нет, прежде чем делать я преревернул кучу литературы. И стандарт в первую очередь. Просто эта фигня отказалась работать по стандарту, вот я от безысходности и начал тыкать. А ошибка опечатка была не там. вот где:
Content-type: text/alternative;  boundary="==52803978d55bb25cb00b8397b03b4f68"

А вообще еще раз спасибо, из Вашего примера я тоже извлек массу нового)))

  Ответить  
 
 автор: Николай2357   (10.09.2009 в 18:24)   письмо автору
 
   для: Николай2357   (10.09.2009 в 14:40)
 

Чтоб не быть голословным, вот что получилось в итоге с Вашей помощью:

<?php 
/**   
 *    name:    Mailer Class  
 *    reliased:    10 sept 2009  
 *    author:   IRBIS-team  
 *    license:    GPL (General Public License)  
**/ 

class Mailer  
{  
    private 
$n "\n";      
    private 
$to;  
    private 
$from;      
    private 
$subject;      
    private 
$message;  
    private 
$attachment;  
    private 
$boundary1;  
    private 
$boundary2;      
    private 
$html false;  
    private 
$attach false;      
    private 
$multipart;  
    private 
$errors = array();  
    private 
$dummy 'Your post client does not support specification MIME 1.0   
    For correct display of the letter you should replace the post program.'
;          
/*   
*    Конструктор. Устанавливаем символ переноса строкии и разделители,   
*     а так же готовим сообщение в текстовом виде           
*/      
   
function __construct($message false)  
   {  
      if(
substr(PHP_OS03) == "WIN")  
      
$this->"\r\n";  
        
      
$this->boundary1 '=='md5(uniqid(time()));  
      
$this->boundary2 '=='md5(uniqid(time()));  
                    
      if(
$message)  
      {                    
          
$this->message $message;  
          
$header  =  '--'$this->boundary2 $this->n;  
          
$header  .= 'Content-type: text/plain; charset="utf-8"'$this->n;  
          
$header  .= 'Content-Transfer-Encoding: base64'$this->n$this->n;  
          
$this->multipart  $header chunk_split(base64_encode($this->message)) . $this->n;        
      }  
      else  
      {  
          
$this->errors[] = 'There is no message text';        
      }  
    } 
/*        
* Прикрепление файла 
*/    
   
function attacheFile($file false$file_name false)  
   {     
        
      if(
$file)  
      {   
          
$this->attach true;                         
            
          if(
file_exists($file))  
          {  
              if(!
$file_name)  
                 
$file_name basename($file);  
              else  
                 
$file_name '=?utf-8?b?'base64_encode($file_name) .'?=' strrchr(basename($file), ".");                
                
              
$this->attachment   'Content-type: application/octet-stream; name="'$file_name .'"' $this->n;   
              
$this->attachment  .= 'Content-disposition: attachment;  filename="'$file_name .'"'$this->n;   
              
$this->attachment  .= 'Content-Transfer-Encoding: base64' $this->$this->n;  
              
$this->attachment  .=  chunk_split(base64_encode(file_get_contents($file))) . $this->$this->n;                            
          }  
          else  
          {  
              
$this->errors[] = 'There is no file on the specified way';                
          }  
      }  
      else  
      {  
          
$this->errors[] = 'There is no file';        
      }   
   } 
/*  
* Cообщение в HTML формате 
*/    
   
function setHtml()  
   {  
     
     
$this->html true;  
     
$this->multipart  '';        
        
     if(
$this->attach)  
     {  
         
$this->multipart  '--'$this->boundary1 $this->n;  
         
$this->multipart .= 'Content-type: multipart/alternative; boundary="'$this->boundary2 .'"'$this->n.$this->n;        
         
$this->multipart .= $this->dummy $this->$this->n;        
     }  
              
     
$this->multipart .=  $this->headers;   
     
$this->multipart .= chunk_split(base64_encode(strip_tags($this->message))) . $this->n;    
     
$this->multipart .=  '--'$this->boundary2 $this->n;        
     
$this->multipart .= 'Content-type: text/html; charset="utf-8"'$this->n;  
     
$this->multipart .= 'Content-Transfer-Encoding: base64'$this->n$this->n;  
     
$this->multipart .= chunk_split(base64_encode($this->message)) . $this->n;   
   } 
/*     
* Метод формирования адреса "кому" 
*/    
   
function createTo($to false)  
   {  
      if(!
$to)  
         
$this->errors[] = 'There is no addressee';   
      elseif(!
preg_match("/^[a-z0-9_\.-]+@([a-z0-9]+\.)+[a-z]{2,4}$/i"$to)) 
          
$this->errors[] = 'The e-mail address is not correct';  
       else 
         
$this->to $to
   }  
/*    
* Метод формирования адреса "от кого" 
*/    
   
function createFrom($from false)  
   {  
      if(
$from)     
         
$this->from trim(preg_replace('/[\r\n]+/'' '$from));  
      else  
         
$this->errors[] = 'There is no sender';        
   }  
/*       
* Метод формирования темы письма  
*/    
   
function createSubject($subject false)  
   {  
      if(
$subject)  
          
$this->subject '=?utf-8?b?'base64_encode($subject) .'?=';  
      else  
          
$this->errors[] = 'There is no theme';        
   }  
/*    
* Метод формирования заголовков и сообщения с вложением  
*/  
   
function createMail()  
   {  
     
         
$header  'From: <'$this->from .'>'$this->n;  
         
$header .= 'MIME-Version: 1.0'$this->n;  
         
$header .= 'Date: 'date('D, d M Y h:i:s O') . $this->n;  
                   
         if(
$this->html && !$this->attach)  
         {  
             
$header .= 'Content-type: multipart/alternative; boundary="'$this->boundary2 .'"'$this->n;           
         }  
         elseif(
$this->attach)  
         {  
             
$header .= 'Content-type: multipart/mixed; boundary="'$this->boundary1 .'"'$this->n;  
             
$this->multipart  .= '--'$this->boundary2 .'--'$this->n;  
             
$this->multipart  .= '--'$this->boundary1 $this->n;  
             
$this->multipart  .= $this->attachment;  
             
$this->multipart  .= '--'$this->boundary1 .'--'$this->n;                     
         }  
         else  
         {  
             
$header .= 'Content-type: multipart/related; boundary="'$this->boundary2 .'"'$this->n;  
         }  
           
         if(
$this->attach)  
             
$this->multipart $this->dummy $this->$this->$this->multipart;  
           
         return 
$header;        
   }   
/*       
* Диагностика ошибок 
*/      
   
function checkData()  
   {  
      if(
count($this->errors))   
          return 
"Mailer error: \n"implode("\n"$this->errors);  
      else  
          return 
false;    
   }  
/*         
* Отправка 
*/   
   
function sendMail()  
   {           
         if(!
$error $this->checkData())  
         {     
           
         
$header $this->createMail();  
                     
            if(!
mail($this->to$this->subject$this->multipart$header'-f'$this->from))  
                return 
'Letter sending is impossible';  
            else  
                return 
NULL;  
        }  
        else  
        {  
            return 
$error;  
        }  
   }    
}  
/*  
* Адрес получателя 
*/  
  
$to 'my-email@mail.ru'
/*       
* Адрес отправителя   
*/ 
  
$from 'email@yandex.ru';  
/*  
* Тема письма  
*/ 
  
$subject 'Табе пакет';  
/*  
* Текст сообщения. Можно в формате HTML  
*/    
  
$message '<h1 style="color:blue">Вот такое вот письмо</h1>';  
/*  
* Путь до прикрепляемого файла  
*/ 
  
$file 'file.gif';  
/*  
* Подключаем класс  
*/ 
 // include 'mailer.php';   
/*     
* Создаем новый объект  
*/ 
  
$mail = new Mailer($message);   
/*     
* Если нужно - прикрепляем файл. Если нет - не пишем этот вызов  
* Второй параметр указывать не обязательно. Тогда сохранится родное имя файла. 
*/  
  
$mail -> attacheFile($file'kartinko');  
/*  
* Выставляем тип HTML.  Если простой текст - не пишем этот вызов  
*/  
  
$mail -> setHtml();  
/*  
* Кому, от кого, тема.  
*/ 
  
$mail -> createTo($to);  
  
$mail -> createFrom($from);  
  
$mail -> createSubject($subject); 
/*    
* Отправка. При удачной вернет NULL, при фиаско - текст ошибки  
*/ 
  
$error $mail -> sendMail(); 
/*    
* Ну а так можно этот текст вывести и посмотреть. 
*/  
  
echo nl2br($error);

Вроде бы всё учел... Или нет?

  Ответить  
 
 автор: Trianon   (10.09.2009 в 19:08)   письмо автору
 
   для: Николай2357   (10.09.2009 в 18:24)
 

навскидку
$header .= $this->n .'dummy text part 1';
это чушь. Я такого не писал.

Вообще же это для Вас была фраза, а не для протокола.
Обычно там пишут мол "Если Вы читаете эти строки, значит Ваш клиент спецификацию MIME 1.0 не поддерживает, и Вы можете идти лесом его апгрейдить. "

  Ответить  
 
 автор: Николай2357   (10.09.2009 в 19:15)   письмо автору
 
   для: Trianon   (10.09.2009 в 19:08)
 

То то я не нашел в спецификации)))
Ясно, буду впредь осторожен с Вашими советами. Я же привык уже, что Вы все протоколы знаете лучше мануала.

  Ответить  
 
 автор: Trianon   (10.09.2009 в 19:22)   письмо автору
 
   для: Николай2357   (10.09.2009 в 19:15)
 

Да не с советами нужно быть осторожным, а с реализацией.
Когда я сказал, что $header .= $this->n .'dummy text part 1'; это чушь, я имел в виду вовсе не "dummy text part 1" ,
а Ваше стремление зачем-то забросить эту строку именно в заголовок (а не в тело сообщения).
Вынужден еще раз указать на (10.09.2009 в 10:46)

  Ответить  
 
 автор: Николай2357   (10.09.2009 в 19:43)   письмо автору
 
   для: Trianon   (10.09.2009 в 19:22)
 

Действительно чушь... Хоть и косметическая, но от этого не легче. Спасибо.

  Ответить  
 
 автор: Николай2357   (10.09.2009 в 19:53)   письмо автору
 
   для: Николай2357   (10.09.2009 в 19:43)
 

Не могу найти этого места, хоть застрелите... Что лесом то я напишу, а вот dummy никак не вижу... Что это?

  Ответить  
 
 автор: Trianon   (10.09.2009 в 20:18)   письмо автору
 
   для: Николай2357   (10.09.2009 в 19:53)
 

   There appears to be room for additional information prior to the
   first boundary delimiter line and following the final boundary
   delimiter line.  These areas should generally be left blank, and
   implementations must ignore anything that appears before the first
   boundary delimiter line or after the last one.

   NOTE:  These "preamble" and "epilogue" areas are generally not used
   because of the lack of proper typing of these parts and the lack of
   clear semantics for handling these areas at gateways, particularly
   X.400 gateways.  However, rather than leaving the preamble area
   blank, many MIME implementations have found this to be a convenient




Freed & Borenstein          Standards Track                    [Page 20]

RFC 2046                      Media Types                  November 1996


   place to insert an explanatory note for recipients who read the
   message with pre-MIME software, since such notes will be ignored by
   MIME-compliant software.

   NOTE:  Because boundary delimiters must not appear in the body parts
   being encapsulated, a user agent must exercise care to choose a
   unique boundary parameter value.  The boundary parameter value in the
   example above could have been the result of an algorithm designed to
   produce boundary delimiters with a very low probability of already
   existing in the data to be encapsulated without having to prescan the
   data.  Alternate algorithms might result in more "readable" boundary
   delimiters for a recipient with an old user agent, but would require
   more attention to the possibility that the boundary delimiter might
   appear at the beginning of some line in the encapsulated part.  The
   simplest boundary delimiter line possible is something like "---",
   with a closing boundary delimiter line of "-----".

   As a very simple example, the following multipart message has two
   parts, both of them plain text, one of them explicitly typed and one
   of them implicitly typed:

     From: Nathaniel Borenstein <nsb@bellcore.com>
     To: Ned Freed <ned@innosoft.com>
     Date: Sun, 21 Mar 1993 23:56:48 -0800 (PST)
     Subject: Sample message
     MIME-Version: 1.0
     Content-type: multipart/mixed; boundary="simple boundary"

     This is the preamble.  It is to be ignored, though it
     is a handy place for composition agents to include an
     explanatory note to non-MIME conformant readers.

     --simple boundary

     This is implicitly typed plain US-ASCII text.
     It does NOT end with a linebreak.
     --simple boundary
     Content-type: text/plain; charset=us-ascii

     This is explicitly typed plain US-ASCII text.
     It DOES end with a linebreak.

     --simple boundary--

     This is the epilogue.  It is also to be ignored.

  Ответить  
 
 автор: Николай2357   (10.09.2009 в 21:10)   письмо автору
 
   для: Trianon   (10.09.2009 в 20:18)
 

Где глаза мои были... Спасибо еще раз. Понял теперь.
Ооставил так, как память, хотя как видно не сильно это практикуется... Кучу почты пересмотрел, ни где не нашел.

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования