У меня проблема с отправкой электронной почты с несколькими вложениями. Вот код:
<?php if(isset($_POST['sendEmail'])) { foreach($_FILES['uploadEmail']['error'] as $key=>$value){ if(!$_FILES['uploadEmail']['error'][$key]){ $target_path = ""; $target_path = $target_path . basename( $_FILES['uploadEmail']['name'][$key]); if(move_uploaded_file($_FILES['uploadEmail']['tmp_name'][$key], $target_path)){ $files[] = $_FILES['uploadEmail']['name'][$key]; } } } $toEmails = explode(",",$_POST['toEmail']); $count = count($toEmails); $i = 0; $j = 1; $k = 100; $bcc = ''; while($i<$count){ $bcc .= $toEmails[$i].","; if($j==$k || $i==$count-1){ $j=1; //echo $bcc.'<br />'.$sub.'<br />'.$message.'<br /><br />'; $from = 'test@gmail.com'; $sub = $_POST['subject']; $message = $_POST['message']; ///////////////////////// $headers = 'From:'. $from . "\r\n"; $headers .= "Bcc:". $bcc . "\r\n"; // boundary $semi_rand = md5(time()); $mime_boundary = "==Multipart_Boundary_x{$semi_rand}x"; // headers for attachment $headers .= "\nMIME-Version: 1.0\n" . "Content-Type: multipart/mixed;\n" . " boundary=\"{$mime_boundary}\""; // multipart boundary $message = "This is a multi-part message in MIME format.\n\n" . "--{$mime_boundary}\n" . "Content-Type: text/html; charset=\"iso-8859-1\"\n" . "Content-Transfer-Encoding: 7bit\n\n" . $message . "\n\n"; $message .= "--{$mime_boundary}\n"; // preparing attachments for($x=0;$x<count($files);$x++){ $file = fopen($files[$x],"rb"); //echo "<br>".filesize($files[$x]); $data = fread($file,filesize($files[$x])); fclose($file); $data = chunk_split(base64_encode($data)); $message .= "Content-Type: {\"application/octet-stream\"};\n" . " name=\"$files[$x]\"\n" . "Content-Disposition: attachment;\n" . " filename=\"$files[$x]\"\n" . "Content-Transfer-Encoding: base64\n\n" . $data . "\n\n"; $message .= "--{$mime_boundary}\n"; } // send ///////////////////////// mail('',$sub,$message,$headers); $bcc = ''; }else{ $j++; } $i++; } } ?> <html> <head> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js"></script> <script src="http://js.nicedit.com/nicEdit-latest.js" type="text/javascript"></script> <script type="text/javascript">bkLib.onDomLoaded(function() { new nicEditor().panelInstance('message'); // new nicEditor({fullPanel : true}).panelInstance('area2'); });</script> </head> <body> <form method="POST" enctype="multipart/form-data"> <table> <tr><td><label for="toEmail">Send To : </label></td><td><textarea id="toEmail" name="toEmail" cols="100" rows="10"></textarea></td></tr> <tr><td><label for="subject">Subject : </label></td><td><input type="text" name="subject" id="subject" size="98"></td></tr> <tr><td><label for="toEmail">Message : </label></td><td><textarea id="message" name="message" cols="100" rows="10"></textarea></td></tr> <tr><td><label for="upload[]">Attachments:</label></td><td></td></tr> <tr><td><label>1</label></td><td><input type="file" name="uploadEmail[]"></td></tr> <tr><td><label>2</label></td><td><input type="file" name="uploadEmail[]"></td></tr> <tr><td><label>3</label></td><td><input type="file" name="uploadEmail[]"></td></tr> <tr><td><label>4</label></td><td><input type="file" name="uploadEmail[]"></td></tr> <tr><td><label>5</label></td><td><input type="file" name="uploadEmail[]"></td></tr> <tr><td><label>6</label></td><td><input type="file" name="uploadEmail[]"></td></tr> <tr><td><label>7</label></td><td><input type="file" name="uploadEmail[]"></td></tr> <tr><td><label>8</label></td><td><input type="file" name="uploadEmail[]"></td></tr> <tr><td><label>9</label></td><td><input type="file" name="uploadEmail[]"></td></tr> <tr><td><label>10</label></td><td><input type="file" name="uploadEmail[]"></td></tr> <tr><td colspan="2" align="center"><input type="submit" value="Send Email" name="sendEmail" id="sendEmail"></td></tr> </table> </form> <body> </html>
Я получил почту, но не смог найти никаких вложений. Кто-нибудь знает, что может быть неправильным?
Вот адрес электронной почты, который я получил по почте:
MIME-Version: 1.0 Content-Type: multipart / mixed; граница = "== Multipart_Boundary_x2d454346f03d2c19cfefc838ce4d8623x" Это многокомпонентное сообщение в формате MIME. - == Multipart_Boundary_x2d454346f03d2c19cfefc838ce4d8623x Content-Type: text / html; кодировка = "ISO-8859-1" Content-Transfer-Encoding: 7 бит ds fsdfsdfsdfsdfsdfsdfsf sffdfsdfsdfs fsdfdf sdf s - == Multipart_Boundary_x2d454346f03d2c19cfefc838ce4d8623x Content-Type: {"application / octet-stream"}; имя = "/ TMP / phpHFTvAw" Content-Disposition: вложение; имя файла = "Lighthouse.jpg" Content-Transfer-Encoding: base64 - == Multipart_Boundary_x2d454346f03d2c19cfefc838ce4d8623x Content-Type: {"application / octet-stream"}; имя = "/ TMP / phpyX67HR" Content-Disposition: вложение; имя файла = "Penguins.jpg" Content-Transfer-Encoding: base64 - == Multipart_Boundary_x2d454346f03d2c19cfefc838ce4d8623x
Я предлагаю использовать PHPMailer для отправки писем с прикреплениями:
<?php require 'PHPMailerAutoload.php'; // If this file is not located in the same directory, use __DIR__ . "/path/to/PHPMailerAutoload.php" $mail = new PHPMailer; $mail->From = 'from@example.com'; $mail->FromName = 'Mailer'; $mail->addAddress('joe@example.net', 'Joe User'); // Add a recipient $mail->addAddress('ellen@example.com'); // Name is optional $mail->addReplyTo('info@example.com', 'Information'); $mail->addCC('cc@example.com'); $mail->addBCC('bcc@example.com'); $mail->addAttachment('/var/tmp/file.tar.gz'); // Add attachments $mail->addAttachment('/tmp/image.jpg', 'new.jpg'); // Optional name $mail->isHTML(true); // Set email format to HTML $mail->Subject = 'Here is the subject'; $mail->Body = 'This is the HTML message body <b>in bold!</b>'; $mail->AltBody = 'This is the body in plain text for non-HTML mail clients'; if(!$mail->send()) { echo 'Message could not be sent.'; echo 'Mailer Error: ' . $mail->ErrorInfo; } else { echo 'Message has been sent'; } ?>
Скачать и документацию: здесь .
Есть несколько проблем с вашим кодом, который я подробно описал ниже.
$headers = 'From:'. $from . "\r\n"; $headers .= "Bcc:". $bcc . "\r\n"; ... // headers for attachment $headers .= "\nMIME-Version: 1.0\n" . "Content-Type: multipart/mixed;\n" . " boundary=\"{$mime_boundary}\""; // multipart boundary $message = "This is a multi-part message in MIME format.\n\n" . "--{$mime_boundary}\n" . "Content-Type: text/html; charset=\"iso-8859-1\"\n" . "Content-Transfer-Encoding: 7bit\n\n" . $message . "\n\n"; $message .= "--{$mime_boundary}\n";
Строки в сообщениях электронной почты разделены последовательностями CRLF
( \r\n
). Неясно, преобразует ли функция mail()
\n
в \r\n
или нет, но учитывая, что ваши заголовки From:
и Bcc:
используют \r\n
, они, вероятно, должны использовать их. Ваш вывод также указывает на то, что окончание строк, возможно, отсутствует или искажено.
Из руководства PHP :
Если сообщения не получены, попробуйте использовать только LF (\ n). Некоторые почтовые агенты Unix (в частности, qmail ) автоматически заменяют LF CRLF (что приводит к удвоению CR, если используется CRLF). Это должно быть последним средством, поскольку оно не соответствует »RFC 2822 .
$message .= "Content-Type: {\"application/octet-stream\"};\n" . " name=\"$files[$x]\"\n" .
Удалите фигурные скобки и кавычки:
$message .= "Content-Type: application/octet-stream\n" . " name=\"$files[$x]\"\n" .
Кроме того, параметр name
устарел в пользу параметра filename
в заголовке Content-Disposition
. Если вы хотите сохранить его для некоторой обратной совместимости, вы должны удалить из него путь. (Ваш вывод указывает, что вы используете tmp_name
а не name
).
$message .= "--{$mime_boundary}\n"; // preparing attachments for($x=0;$x<count($files);$x++){ ... $message .= /* body part */; $message .= "--{$mime_boundary}\n"; }
Обратите внимание, что конечный разделитель должен иметь две концевые тире. Вставьте разделительные разделители в начале цикла и добавьте разделитель закрытия после цикла:
// preparing attachments for($x=0;$x<count($files);$x++){ $message .= "--{$mime_boundary}\n"; ... $message .= /* body part */; } $message .= "--{$mime_boundary}--\n";
См. Раздел синтаксиса электронной почты ниже.
$k = 100; ... while($i<$count){ $bcc .= $toEmails[$i].","; if($j==$k || $i==$count-1){ ... $headers .= "Bcc:". $bcc . "\r\n";
в$k = 100; ... while($i<$count){ $bcc .= $toEmails[$i].","; if($j==$k || $i==$count-1){ ... $headers .= "Bcc:". $bcc . "\r\n";
Обратите внимание, что в сообщениях электронной почты существуют ограничения длины строки. RFC 5322 :
... Каждая строка символов ДОЛЖНА быть не более 998 символов, и ДОЛЖНО быть не более 78 символов, исключая CRLF.
Возможно, вам захочется вырезать вашу Bcc
короче или ввести FWS (Folding White Space) :
$bcc .= $toEmails[$i].",\r\n "; /* FWS */
Некоторые дополнительные проблемы или уведомления, которые могут быть полезными или могут быть полезными:
foreach($_FILES['uploadEmail']['error'] as $key=>$value){ if(!$_FILES['uploadEmail']['error'][$key]){
Последняя строка такая же, как:
if(!$value){
$target_path = ""; $target_path = $target_path . basename( $_FILES['uploadEmail']['name'][$key]);
Я предполагаю, что $target_path
должен быть инициализирован каталогу загрузки.
$toEmails = explode(",",$_POST['toEmail']);
Как правило, вы не должны позволять случайным пользователям предоставлять исходящие адреса электронной почты, но я подозреваю, что это внутреннее приложение для доверенных пользователей.
Это отрывок из того, как выглядит структура тела сообщений с несколькими частями в соответствии с RFC 2046. (Синтаксис BNF, несколько упрощен.)
multipart-body: = [преамбула CRLF] пограничная граница CRLF инкапсуляция тела-части * крупный ограничитель [Эпилог CRLF] граница границы раздела: = "-" body-part: = MIME-частичные заголовки [CRLF * OCTET] инкапсуляция: = разделитель CRLF часть тела разделитель: = граница CRLF close-delimiter: = разделитель "-"