如何从PHP表单发送带附件的电子邮件?

Nat*_*ong 5 php email attachment

如何从PHP表单发送带附件的电子邮件?

Nat*_*ong 12

最好使用现有工具,正如其他人在他们的答案中所建议的那样.但是,如果你想自己动手或者只是了解方法,请继续阅读.

HTML

您的HTML中只有两个要求用于发送文件附件.

  • 您的表单需要具有以下属性: enctype="multipart/form-data"
  • 你需要至少一个字段<input type="file" name="examplefile">.这允许用户浏览要附加的文件.

如果您同时拥有这两个文件,浏览器将上传任何附加文件以及表单提交.

附注:这些文件在服务器上保存为临时文件.对于此示例,我们将获取其数据并通过电子邮件发送,但如果将临时文件移动到永久位置,则您刚刚创建了文件上载表单.

MIME电子邮件格式

本教程非常适合理解如何在PHP中构建MIME电子邮件(可以包含HTML内容,纯文本版本,附件等).我用它作为起点.

基本上,你做三件事:

  • 事先声明此电子邮件中包含多种类型的内容
  • 声明一个文本字符串,用于分隔不同的部分
  • 定义每个部分并坚持使用适当的内容.对于文件附件,您必须指定类型并以ASCII格式对其进行编码.
    • 每个部分都有content-type这样的image/jpgapplication/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 ) ) 
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用在相关的临时文件中获取数据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.';
    }
  }    
}
Run Code Online (Sandbox Code Playgroud)

如果你想看看这里发生了什么,请将呼叫注释掉,mail()然后将输出回显到你的屏幕.


Ant*_*nna 1

为了发送实际的电子邮件,我建议使用PHPMailer 库,它使一切变得更加容易。