正如其他人在回答中所建议的那样,最好使用现有工具。但是,如果您想自己动手或只是了解如何操作,请继续阅读。
HTML
在您的 HTML 中发送文件附件实际上只有两个要求。
- 你的表单需要有这个属性:
enctype="multipart/form-data"
- 您至少需要一个字段,例如
<input type="file" name="examplefile">。这允许用户浏览要附加的文件。
如果您同时具备这两个条件,浏览器会将所有附件连同表单提交一起上传。
旁注:这些文件在服务器上保存为临时文件。在本例中,我们将获取他们的数据并通过电子邮件发送,但如果您将临时文件移动到永久位置,则您只是创建了一个文件上传表单。
MIME 电子邮件格式
This tutorial 非常适合理解如何在 PHP 中构建 MIME 电子邮件(可以包含 HTML 内容、纯文本版本、附件等)。我以它为起点。
基本上,你会做三件事:
- 预先声明此电子邮件将包含多种类型的内容
- 声明一个用于分隔不同部分的文本字符串
- 定义每个部分并坚持适当的内容。对于文件附件,您必须指定类型并以 ASCII 对其进行编码。
- 每个部分都有一个
content-type,例如image/jpg 或application/pdf. 更多信息可以在here 找到。 (我的示例脚本使用内置 PHP 函数从每个文件中提取这些信息。)
PHP
提交表单后,浏览器上传的任何文件(参见 HTML 部分)都将通过 $_FILES 变量提供,该变量包含“通过 HTTP POST 方法上传到当前脚本的项目的关联数组。 '
$_FILES 上的documentation 很糟糕,但是在上传之后,您可以运行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 有一些限制附件大小的设置。请参阅this discussion 了解更多信息。
一个示例 PHP 函数
我创建了以下函数,该函数可以包含在页面中并用于收集通过表单提交的任何文件附件。随意使用它和/或根据您的需要调整它。
总附件限制是任意的,但大量可能会使mail() 脚本陷入困境或被发送或接收电子邮件服务器拒绝。进行自己的测试。
(注意:PHP 中的mail() 函数依赖于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() 的调用,并让它将输出回显到您的屏幕上。