Отправлять PHP HTML почту с вложениями - PullRequest
11 голосов
/ 01 марта 2012

У меня проблема: до сегодняшнего дня я отправлял HTML-письма с PHP, используя заголовок, содержащий

Content-type: text/html;

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

Content-Type: multipart/mixed;

Теперь, с multipart/mixed, остальная часть письма, то есть обычный текст, отображается как текст / обычный текст. Как я могу понять, что вложения работают, а почтовый текст по-прежнему HTML?

Ответы [ 4 ]

26 голосов
/ 19 ноября 2012

Я пытался ответить 1 в течение нескольких часов безуспешно.Я нашел решение здесь: http://www.finalwebsites.com/forums/topic/php-e-mail-attachment-script

Работает как шарм - менее 5 минут!Возможно, вы захотите изменить (как я) первый тип содержимого с text / plain на text / html.

Вот моя слегка измененная версия для обработки нескольких вложений:

function mail_attachment($files, $path, $mailto, $from_mail, $from_name, $replyto, $subject, $message) {
$uid = md5(uniqid(time()));

$header = "From: ".$from_name." <".$from_mail.">\r\n";
$header .= "Reply-To: ".$replyto."\r\n";
$header .= "MIME-Version: 1.0\r\n";
$header .= "Content-Type: multipart/mixed; boundary=\"".$uid."\"\r\n\r\n";
$header .= "This is a multi-part message in MIME format.\r\n";
$header .= "--".$uid."\r\n";
$header .= "Content-type:text/html; charset=iso-8859-1\r\n";
$header .= "Content-Transfer-Encoding: 7bit\r\n\r\n";
$header .= $message."\r\n\r\n";

    foreach ($files as $filename) { 

        $file = $path.$filename;

        $file_size = filesize($file);
        $handle = fopen($file, "r");
        $content = fread($handle, $file_size);
        fclose($handle);
        $content = chunk_split(base64_encode($content));

        $header .= "--".$uid."\r\n";
        $header .= "Content-Type: application/octet-stream; name=\"".$filename."\"\r\n"; // use different content types here
        $header .= "Content-Transfer-Encoding: base64\r\n";
        $header .= "Content-Disposition: attachment; filename=\"".$filename."\"\r\n\r\n";
        $header .= $content."\r\n\r\n";
    }

$header .= "--".$uid."--";
return mail($mailto, $subject, "", $header);
}
10 голосов
/ 01 марта 2012

Чтобы отправить электронное письмо с вложением, нам нужно использовать MIME-тип multipart / mixed, который указывает, что смешанные типы будут включены в электронное письмо.Кроме того, мы хотим использовать многочастный / альтернативный тип MIME для отправки как электронной, так и текстовой версии электронной почты. Посмотрите на пример:

<?php 
//define the receiver of the email 
$to = 'youraddress@example.com'; 
//define the subject of the email 
$subject = 'Test email with attachment'; 
//create a boundary string. It must be unique 
//so we use the MD5 algorithm to generate a random hash 
$random_hash = md5(date('r', time())); 
//define the headers we want passed. Note that they are separated with \r\n 
$headers = "From: webmaster@example.com\r\nReply-To: webmaster@example.com"; 
//add boundary string and mime type specification 
$headers .= "\r\nContent-Type: multipart/mixed; boundary=\"PHP-mixed-".$random_hash."\""; 
//read the atachment file contents into a string,
//encode it with MIME base64,
//and split it into smaller chunks
$attachment = chunk_split(base64_encode(file_get_contents('attachment.zip'))); 
//define the body of the message. 
ob_start(); //Turn on output buffering 
?> 
--PHP-mixed-<?php echo $random_hash; ?>  
Content-Type: multipart/alternative; boundary="PHP-alt-<?php echo $random_hash; ?>" 

--PHP-alt-<?php echo $random_hash; ?>  
Content-Type: text/plain; charset="iso-8859-1" 
Content-Transfer-Encoding: 7bit

Hello World!!! 
This is simple text email message. 

--PHP-alt-<?php echo $random_hash; ?>  
Content-Type: text/html; charset="iso-8859-1" 
Content-Transfer-Encoding: 7bit

<h2>Hello World!</h2> 
<p>This is something with <b>HTML</b> formatting.</p> 

--PHP-alt-<?php echo $random_hash; ?>-- 

--PHP-mixed-<?php echo $random_hash; ?>  
Content-Type: application/zip; name="attachment.zip"  
Content-Transfer-Encoding: base64  
Content-Disposition: attachment  

<?php echo $attachment; ?> 
--PHP-mixed-<?php echo $random_hash; ?>-- 

<?php 
//copy current buffer contents into $message variable and delete current output buffer 
$message = ob_get_clean(); 
//send the email 
$mail_sent = @mail( $to, $subject, $message, $headers ); 
//if the message is sent successfully print "Mail sent". Otherwise print "Mail failed" 
echo $mail_sent ? "Mail sent" : "Mail failed"; 
?>

Как видите, отправка электронного письма с вложениемэто легко сделать.В предыдущем примере мы имеем составной / смешанный MIME-тип, а внутри него мы имеем составной / альтернативный MIME-тип, который определяет две версии письма.Чтобы включить вложение в наше сообщение, мы читаем данные из указанного файла в строку, кодируем их с помощью base64, разделяем их на более мелкие куски, чтобы убедиться, что они соответствуют спецификациям MIME, а затем включаем их в качестве вложения.

3 голосов
/ 19 июня 2013

SWIFTMAIL в php работает gr8 для прикрепления к письмам.

Загрузите swiftmailer здесь http://swiftmailer.org/

Посмотрите на простой код ниже

ВКЛЮЧИТЕ ФАЙЛ

require_once('path/to/swiftMailer/lib/swift_required.php');

СОЗДАТЬ ТРАНСПОРТ

//FOR SMTP
// Create the Transport
$transport = Swift_SmtpTransport::newInstance('smtp.googlemail.com', 465, 'ssl')
    ->setUsername('user@gmail.com')
    ->setPassword('gmailpassword');

ИЛИ

//FOR NORMAL MAIL
$transport = Swift_MailTransport::newInstance();

ОБЪЕКТ ПОЧТЫ

// Create the Mailer using your created Transport
$mailer = Swift_Mailer::newInstance($transport);

СОЗДАТЬ ОБЪЕКТ СООБЩЕНИЯ

$message = Swift_Message::newInstance($subject)
    ->setFrom(array($from => $from))
    ->setTo($to)
    ->setBody($body);
$message->attach(Swift_Attachment::fromPath($filepath));

ОТПРАВИТЬСООБЩЕНИЕ

$result = $mailer->send($message);
1 голос
/ 08 апреля 2015

Если вы действительно хотите научиться форматировать интернет-сообщение, вам следует обратиться к его запросу на комментарии (он же RFC).* «1001 * RFC2045 », выпущенный в ноябре 1996 года.

Формат, который определяется как-то очень строгим и должен соблюдаться как есть.

В основном сообщение содержит заголовок и тело.Заголовок определяет тип сообщения, способ его форматирования, некоторые другие поля, которые отличаются от одного типа к другому.

Тело состоит из разных сущностей.Сущность может быть, например, простым текстом типа «Привет!»но также может быть изображением, вложением, чем угодно.

ПРИМЕЧАНИЕ В следующих примерах все, что заключено в квадратные скобки (например, {hello}), должно быть заменено вашим реальным значением,Любой перевод строки в действительности является CRLF (т. Е. ASCII 13 + ASCII 10).Где вы видите два CRLF придерживаться его.Это был бы худший момент, чтобы показать, насколько вы креативны.

В основном для сообщения электронной почты с вложениями заголовок должен выглядеть следующим образом:

MIME-Version: 1.0
To: {email@domain}
Subject: {email-subject}
X-Priority: {2 (High)}
Content-Type: multipart/mixed; boundary="{mixed-boudary}"

В приведенном выше примере{mixed-boudary} может быть любым уникальным хеш-значением, например, 000008050800060107020705. Остальные говорят сами за себя.

Теперь, каждый раз, когда мы хотим добавить новый объект к сообщению (например, тело сообщения, изображение(вложение), мы должны сообщить агенту электронной почты, что новый раздел , т.е.префикс этой сущности со значением {mixed-border}.Мы называем это «открыть границу».Обратите внимание, что, открывая границу, мы не вставляем эту границу, как было определено изначально, мы используем еще 2 знака минус впереди, например - {mixed-boudary}.Когда мы закрываем границу, мы поступаем аналогичным образом, за исключением того, что мы должны использовать другие 2 знака минус в конце, например - {mixed-boudary} -

--{mixed-boudary}
the entity content
--{mixed-boudary}--

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

Для содержимого тела HTML мой заголовок сущности будет выглядеть так:

Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: 7bit

, поэтому весьтело (заключенное в границы) в конечном итоге будет выглядеть так:

--{mixed-boudary}
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: 7bit

<html>
<head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head>
<body bgcolor="#FFFFFF" text="#000000">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque vel 
dapibus arcu. Duis quam dui, ornare non mi nec, luctus faucibus massa. Vivamus 
quis purus in erat euismod ullamcorper vitae eget dolor. Aliquam tempor erat 
accumsan, consectetur ex et, rhoncus risus.
</body>
</html>

Если нужно вставить другую сущность, мы действуем точно так же, как описано выше.Когда больше нет данных для добавления к сообщению, мы закрываем смешанную границу, т.е.CRLF + - {mixed-boudary} -.

Если по какой-либо причине сущность должна быть вставлена ​​с альтернативным представлением (например, текст сообщения вставляется как в виде простого текста, так и в виде HTML)формат), тогда контент объекта должен быть объявлен с типом содержимого multipart / alternative (хотя глобальный заголовок multipart / mixed все еще остается!).Каждое альтернативное представление будет заключено в эту новую границу.

Полный пример ниже:

MIME-Version: 1.0
To: {email@domain}
Subject: {email-subject}
X-Priority: {2 (High)}
Content-Type: multipart/mixed; boundary="{mixed-boudary}"

--{mixed-boudary}
Content-Type: multipart/alternative; boundary="{alternative-boudary}"

--{alternative-boudary}
Content-Type: text/plain; charset=utf-8;
Content-Transfer-Encoding: 7bit

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque vel 
dapibus arcu. Duis quam dui, ornare non mi nec, luctus faucibus massa. Vivamus 
quis purus in erat euismod ullamcorper vitae eget dolor. Aliquam tempor erat 
accumsan, consectetur ex et, rhoncus risus.

--{alternative-boudary}
Content-Type: text/html; charset=utf-8;
Content-Transfer-Encoding: 7bit

<html>
<head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head>
<body bgcolor="#FFFFFF" text="#000000">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque vel 
dapibus arcu. Duis quam dui, ornare non mi nec, luctus faucibus massa. Vivamus 
quis purus in erat euismod ullamcorper vitae eget dolor. Aliquam tempor erat 
accumsan, consectetur ex et, rhoncus risus.
</body>
</html>

--{alternative-boudary}--

--{mixed-boudary}
Content-Type: application/pdf; name="myfile.pdf"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="myfile.pdf"

JVBERi0xLjINOCAwIG9iag08PCAvTGVuZ3RoIDkgMCBSIC9GaWx0ZXIgL0ZsYXRlRGVjb2Rl
ID4+DXN0cmVhbQ1oQ51bbY/cNg7+BfsfhAUO11w3riW/B7gPaZEAAdpcm06RL8EBzoyn68uM
vZ3xZLv//khKsuUxNaMNiiabpUg+pKiHsmxJEcN/UsgiilP4ab2/+XF1I81vszSqclHIOEpj
sdrf/PC2EFVUpmK1vXkZxVKs1uJlJJVYPYrvPra7XVvvxYdIrE7rL83hhVj97+bNyjUoFam7
FnOB+tubGI3FZEkwmhpKXpVRnqJi0PCyjBJ1DjyOYqWBxxXp/1h3X+ov9abZt434pV0feoG/
ars/xU/9/qEZmm7diJ+abmgOr0TGeFNFEuXx5M4B95Idns/QAaJMI1IpKeXi9+ZhaPafm4NQ
cRwzNpK0iirlRvisRBZpVJa+PP51091kkjBWBXrJxUuZRjIXh0Z8FN3MnB5X5st5Kay9355n

--{mixed-boudary}--

СОВЕТЫ

Используйте предпочитаемый вами вариантпочтовый клиент (мой - Thunderbird) и отправьте себе только одно текстовое сообщение, только один HTML, один смешанный, а затем каждое из предыдущих, но с одним вложенным файлом.Когда вы получаете сообщение, просто изучите его источник (Вид -> Источник сообщения).

@ Edit: очень хорошо документированный пример + пример PHP можно найти по адресу здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...