2012-03-01 4 views
10

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

Content-type: text/html; 

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

Content-Type: multipart/mixed; 

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

+0

каждая часть многочастной почты имеет свой собственный взгляд типа содержимого на источнике надлежащей многочастной почты. – Rufinus

+0

Возможный дубликат [php send email with attachment] (http://stackoverflow.com/questions/4586557/php-send-email-with-attachment). Здесь немало других, которые занимаются электронной почтой и вложениями, просматривают некоторые из связанных. – jprofitt

+0

используйте MIME-заголовок в вашем почтовом шаблоне –

ответ

10

Чтобы отправить электронное письмо с прикрепленным файлом, нам необходимо использовать многопоточный/смешанный тип MIME, который указывает, что смешанные типы будут включены в электронную почту. Кроме того, мы хотим использовать многослойный/альтернативный тип MIME, чтобы отправить как обычный текст и HTML версию email.Have посмотри на примере:

<?php 
//define the receiver of the email 
$to = '[email protected]'; 
//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: [email protected]\r\nReply-To: [email protected]"; 
//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, а затем включите его в качестве вложения.

+16

Собственно, чтобы включить источник, когда вы копируете пасту из какого-то другого источника. Я даже не знаю, является ли это источником, но у них есть комментарии, относящиеся к 2007 году: http://webcheatsheet.com/php/send_email_text_html_attachment.php – Kalle

+1

Да, Санджай откровенно вырезал и вставлял текст с другого сайта и не атрибутировал Это. – user1904273

+0

Эпический сбой Санджай! – wlf

24

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

Работает как шарм менее 5 мин! Возможно, вы захотите изменить (например, я), первый тип содержимого из текста/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); 
} 
+0

Спасибо большое, очень полезно :) – Potheek

+0

Это просто ... у некоторых серверов возникли проблемы с \ r \ n, а вложения и любой html не отображаются. Исправление состоит в том, чтобы использовать PHP_EOL во всех случаях. Вот и все. – Brian

+0

Мне нравится ваш подход. Однако я не мог заставить его отправить Android APK на планшет. Что ж. он отправил APK, но он не будет установлен. – user462990

3

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('[email protected]') 
    ->setPassword('gmailpassword'); 

ИЛИ

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

MAILER ОБЪЕКТ

// 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); 
+0

Это на самом деле выглядит неплохо, я взгляну на Это! Спасибо :) –

1

Если вы действительно хотите узнать, как форматировать Internet Message, то вам следует обратиться его Запрос комментариев (также известный как RFC).Тот, который определяет «Многоцелевые расширения электронной почты Интернета - формат интернет-сообщений», - RFC2045, выпущенный в ноябре 1996 года.

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

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

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

Примечание В следующих примерах все заключенные в скобки (например, {привет}) должно быть заменены с реальным значением. Любая новая строка на самом деле является CRLF (т.е. ASCII 13 + ASCII 10). Где вы видите два CRLF. Было бы худшим моментом, чтобы показать, насколько вы творческий.

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

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

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

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

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

MIME-Version: 1.0 
To: {[email protected]} 
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}-- 

TIPS

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

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

+0

Bravo @Eugen за отличный ответ! – user128216

Смежные вопросы