Как отправить электронное письмо с вложениями из формы PHP?
Для отправки фактического сообщения электронной почты я бы рекомендовал использовать библиотеку PHPMailer , все упростит.
Вероятно, лучше всего использовать существующий инструмент, как другие предложили в своих ответах. Однако, если вы хотите бросить свой собственный или просто понять, продолжайте читать.
В вашем HTML есть только два требования для отправки вложений файлов.
enctype="multipart/form-data"
<input type="file" name="examplefile">
. Это позволяет пользователю просматривать прикрепленный файл. Если у вас есть обоим, браузер загрузит все прикрепленные файлы вместе с отправкой формы .
Замечание: они сохраняются как временные файлы на сервере. В этом примере мы возьмем их данные и отправим их по электронной почте, но если вы переместите временные файлы в постоянное место, вы просто создали форму для загрузки файлов.
Этот учебник отлично подходит для понимания того, как создать электронную почту MIME (которая может содержать содержимое HTML, текстовую версию, вложения и т. Д.) В PHP. Я использовал его в качестве отправной точки.
В принципе, вы делаете три вещи:
content-type
такой как image/jpg
или application/pdf.
Более подробную информацию можно найти здесь . (Мой пример скрипта извлекает эту информацию из каждого файла с помощью встроенных функций PHP.) После $_FILES
формы любые файлы, загруженные браузером (см. Раздел HTML), будут доступны через переменную $_FILES
, которая содержит «Ассоциативный массив элементов, загруженных в текущий скрипт с помощью метода HTTP POST».
Документация на $_FILES
отвратительна, но после загрузки вы можете запустить print_r($_FILES)
чтобы увидеть, как это работает. Он выведет что-то вроде этого:
Array ( [examplefile] => Array ( [name] => your_filename.txt [type] => text/plain [tmp_name] => C:\path\to\tmp\file\something.tmp [error] => 0 [size] => 200 ) )
Затем вы можете получить данные в связанном временном файле с помощью file_get_contents($_FILES['examplefile']['tmp_name'])
.
php.ini
есть некоторые настройки, которые ограничивают размер вложений. См. Обсуждение для получения дополнительной информации.
Я создал следующую функцию, которая может быть включена на страницу и используется для сбора любых прикрепленных файлов в форме. Не стесняйтесь использовать его и / или адаптировать для своих нужд.
Общий лимит прикрепления произволен, но большие суммы могут испортить скрипт mail()
или быть отклонены сервером отправки или получения электронной почты. Сделайте свое собственное тестирование.
(Примечание. Функция mail()
в PHP зависит от информации в php.ini
чтобы знать, как отправить вашу электронную почту.)
function sendWithAttachments($to, $subject, $htmlMessage){ $maxTotalAttachments=2097152; //Maximum of 2 MB total attachments, in bytes $boundary_text = "anyRandomStringOfCharactersThatIsUnlikelyToAppearInEmail"; $boundary = "--".$boundary_text."\r\n"; $boundary_last = "--".$boundary_text."--\r\n"; //Build up the list of attachments, //getting a total size and adding boundaries as needed $emailAttachments = ""; $totalAttachmentSize = 0; foreach ($_FILES as $file) { //In case some file inputs are left blank - ignore them if ($file['error'] == 0 && $file['size'] > 0){ $fileContents = file_get_contents($file['tmp_name']); $totalAttachmentSize += $file['size']; //size in bytes $emailAttachments .= "Content-Type: " .$file['type'] . "; name=\"" . basename($file['name']) . "\"\r\n" ."Content-Transfer-Encoding: base64\r\n" ."Content-disposition: attachment; filename=\"" .basename($file['name']) . "\"\r\n" ."\r\n" //Convert the file's binary info into ASCII characters .chunk_split(base64_encode($fileContents)) .$boundary; } } //Now all the attachment data is ready to insert into the email body. //If the file was too big for PHP, it may show as having 0 size if ($totalAttachmentSize == 0) { echo "Message not sent. Either no file was attached, or it was bigger than PHP is configured to accept."; } //Now make sure it doesn't exceed this function's specified limit: else if ($totalAttachmentSize>$maxTotalAttachments) { echo "Message not sent. Total attachments can't exceed " . $maxTotalAttachments . " bytes."; } //Everything is OK - let's build up the email else { $headers = "From: yourserver@example.com\r\n"; $headers .= "MIME-Version: 1.0\r\n" ."Content-Type: multipart/mixed; boundary=\"$boundary_text\"" . "\r\n"; $body .="If you can see this, your email client " ."doesn't accept MIME types!\r\n" .$boundary; //Insert the attachment information we built up above. //Each of those attachments ends in a regular boundary string $body .= $emailAttachments; $body .= "Content-Type: text/html; charset=\"iso-8859-1\"\r\n" ."Content-Transfer-Encoding: 7bit\r\n\r\n" //Inert the HTML message body you passed into this function .$htmlMessage . "\r\n" //This section ends in a terminating boundary string - meaning //"that was the last section, we're done" .$boundary_last; if(mail($to, $subject, $body, $headers)) { echo "<h2>Thanks!</h2>Form submitted to " . $to . "<br />"; } else { echo 'Error - mail not sent.'; } } }
Если вы хотите посмотреть, что здесь происходит, закомментируйте вызов mail()
и вместо этого произнесите его на экран.
хороший учебник здесь
Код
<?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"; ?>
Возможно, вы захотите проверить SwiftMailer . У этого есть хороший учебник по этому .