Вероятно, лучше использовать существующий инструмент, как другие предложили в своих ответах. Однако, если вы хотите сделать что-то свое или просто понять, продолжайте читать.
HTML
На самом деле в вашем HTML есть только два требования для отправки файловых вложений.
- Ваша форма должна иметь этот атрибут:
enctype="multipart/form-data"
- Вам нужно хотя бы одно поле, например
<input type="file" name="examplefile">
. Это позволяет пользователю найти файл для вложения.
Если у вас есть оба из них, браузер загрузит все вложенные файлы вместе с отправкой формы .
Примечание: они сохраняются как временные файлы на сервере. В этом примере мы возьмем их данные и отправим по электронной почте, но если вы переместите временные файлы в постоянное место, вы только что создали форму для загрузки файлов.
Формат электронной почты MIME
Этот учебник отлично подходит для понимания того, как создать электронную почту MIME (которая может содержать HTML-контент, текстовую версию, вложения и т. Д.) В PHP. Я использовал это как отправную точку.
Обычно вы делаете три вещи:
- Заранее заявите, что в этом письме будет содержаться несколько типов контента
- Объявите строку текста, которую вы будете использовать для разделения различных разделов
- Определите каждый раздел и вставьте соответствующий контент. В случае файловых вложений вы должны указать тип и кодировать их в ASCII.
- Каждый раздел будет иметь
content-type
, например image/jpg
или application/pdf.
. Более подробную информацию можно найти здесь . (Мой пример сценария извлекает эту информацию из каждого файла, используя встроенные функции PHP.)
PHP
После отправки формы любые файлы, загруженные браузером (см. Раздел 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
имеет некоторые настройки, которые ограничивают размер вложения. См. это обсуждение для получения дополнительной информации.
Пример PHP-функции
Я создал следующую функцию, которую можно включить на странице и использовать для сбора любых вложенных файлов, отправленных с формой. Не стесняйтесь использовать его и / или адаптировать для своих нужд.
Общий лимит вложения произвольный, но большие суммы могут привести к сбою сценария 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()
и сделайте так, чтобы он выводил вывод на ваш экран.