PHP邮件发送附件中的Noname文件

时间:2019-06-02 12:03:19

标签: php

我想使用php mail发送附件,但以 noname 发送后发送文件。

这是我的代码:

if( isset($_FILES['attachment'])) 
{ 

    $from_email    = $_POST["contact_email"]; 
    $recipient_email         = 'mohammad.a1381@gmail.com';

    //Load POST data from HTML form 
    $sender_name    = $_POST["contact_names"]; 
    $sender_phone   = $_POST["contact_phone"]; 
    $reply_to_email = $_POST["contact_email"]; 

    $subject        = 'resome'; //subject for the email 
    $message        = $_POST["contact_message"];

    //Get uploaded file data using $_FILES array 
    $tmp_name    = $_FILES['attachment']['tmp_name'];
    $file_name   = $_FILES['attachment']['name'];
    $size        = $_FILES['attachment']['size'];
    $file_type   = $_FILES['attachment']['type'];
    $error       = $_FILES['attachment']['error']; 

    //validate form field for attaching the file 
    if($error > 0) 
    { 
        die('Upload error or No files uploaded'); 
    } 

    //read from the uploaded file & base64_encode content 
    $handle = fopen($tmp_name, "r");
    $content = fread($handle, $size);
    fclose($handle);

    $encoded_content = chunk_split(base64_encode($content)); 

    $boundary = md5("random");

    //header 
    $headers = "MIME-Version: 1.0\r\n"; // Defining the MIME version 
    $headers .= "From:".$from_email."\r\n"; // Sender Email 
    $headers .= "Reply-To: ".$reply_to_email."\r\n";
    $headers .= "Content-Type: multipart/mixed;\r\n";
    $headers .= "boundary = $boundary\r\n"; //Defining the Boundary 

    //plain text  
    $body = "--$boundary\r\n"; 
    $body .= "Content-Type: text/plain; charset=ISO-8859-1\r\n"; 
    $body .= "Content-Transfer-Encoding: base64\r\n\r\n";  
    $body .= chunk_split(base64_encode($message));  

    //attachment 
    $body .= "--$boundary\r\n"; 
    $body .="Content-Type: $file_type; name=".$file_name."\r\n"; 
    $body .="Content-Disposition: attachment; filename=".$file_name."\r\n"; 
    $body .="Content-Transfer-Encoding: base64\r\n"; 
    $body .="X-Attachment-Id: ".rand(1000, 99999)."\r\n\r\n";  
    $body .= $encoded_content;

    $sentMailResult = mail($recipient_email, $subject, $body, $headers); 

    if($sentMailResult )  
    { 
       echo "File Sent Successfully."; 
       unlink($name);
    } 
    else
    { 
       die("Sorry but the email could not be sent. 
                    Please go back and try again!"); 
    } 

1 个答案:

答案 0 :(得分:1)

我使用此代码发送多个附件,并且对我来说效果很好...让我知道这对您来说足够了。我阅读了您的代码,可以使用file_get_contents代替fopenfreadfclose进行改进。

关于md5("random")的安全性还不够,我建议使用md5(uniqid(time())),除了使用$body .= chunk_split(base64_encode($message))编码文件以外,您还对消息部分进行了编码,这是不必要的,因为您发送的是纯文本文字,请注意正确终止您的 mime边界,因为如果使用不正确的顺序可能会导致文件错误地附加到邮件中。

还有一些其他较小的修复方法可以应用,您可以在我的代码中找到它们。

html:

<label for="attachment1">File:</label>&nbsp;<input type="file" id="attachment1" name="attachment[]" size="35">
<label for="attachment2">File:</label>&nbsp;<input type="file" id="attachment2" name="attachment[]" size="35">
<label for="attachment3">File:</label>&nbsp;<input type="file" id="attachment3" name="attachment[]" size="35">

php:

if (isset($_FILES['attachment']['name'])) {
  $semi_rand = md5(uniqid(time()));
  $mime_boundary = "==Multipart_Boundary_x{$semi_rand}x";
  $headers = "From: " . '=?UTF-8?B?' . base64_encode($sender_name) . '?=' . " <$from_email>" . PHP_EOL;
  $headers .= "Reply-To: " . '=?UTF-8?B?' . base64_encode($sender_name) . '?=' . " <$reply_to_email>" . PHP_EOL;
  $headers .= "Return-Path: $from_email" . PHP_EOL;
  $headers .= "MIME-Version: 1.0" . PHP_EOL;
  $headers .= "Content-Type: multipart/mixed;" . PHP_EOL;
  $headers .= " Boundary=\"{$mime_boundary}\"";
  $datamsg = "This is a multi-part message in MIME format." . PHP_EOL . PHP_EOL;
  $datamsg .= "--{$mime_boundary}" . PHP_EOL;
  $datamsg .= "Content-Type: text/plain; Charset=\"UTF-8\"" . PHP_EOL;
  $datamsg .= "Content-Transfer-Encoding: 8bit" . PHP_EOL . PHP_EOL;
  $datamsg .= $message . PHP_EOL . PHP_EOL;
  for ($index = 0; $index < count($_FILES['attachment']['name']); $index++) {
    if ($_FILES['attachment']['name'][$index] != "") {
      $file_name = $_FILES['attachment']['name'][$index];
      $data_file = chunk_split(base64_encode(file_get_contents($_FILES['attachment']['tmp_name'][$index])));
      $datamsg .= "--{$mime_boundary}" . PHP_EOL;
      $datamsg .= "Content-Type: application/octet-stream; Name=\"{$file_name}\"" . PHP_EOL;
      $datamsg .= "Content-Disposition: attachment; Filename=\"{$file_name}\"" . PHP_EOL;
      $datamsg .= "Content-Transfer-Encoding: base64" . PHP_EOL . PHP_EOL . $data_file . PHP_EOL . PHP_EOL;
    }
  }
  $datamsg .= "--{$mime_boundary}--";
}
if (@mail($recipient_email, '=?UTF-8?B?' . base64_encode($subject) . '?=', $datamsg, $headers, "-f$from_email")) {
  exit("Files Sent Successfully");
} else {
  exit("Sorry but the email could not be sent. Please go back and try again!");
}

没有理由unlink($name),因为您不是将文件上传到服务器,而是从tmp服务器目录中读取tmp文件名并将其转换为base64(没有其他方法。)。 ..),您会错过最后一个"--$boundary--";,这对于正确终止邮件部分和附件非常重要。...$headers .= "boundary = $boundary ...不正确,因为需要制表,您可以像{{ 1}} ...

我使用自己的代码进行了测试,并获得成功,我检查了我的敏感数据,所有其余部分都可见并且确定:

$headers .= " Boundary = $boundary