-1

I want to send attachment with php mail but file after sent in noname.

This is my code:

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!"); 
    } 
halfer
  • 19,824
  • 17
  • 99
  • 186
Mohammad Aghayari
  • 1,010
  • 3
  • 15
  • 38

1 Answers1

1

I use this my code to send multiple attachments and works fine for me... let's me know is enough for you. I read your code and can be improved by using file_get_contents instead fopen, fread, fclose.

About md5("random") is not enough safe, I suggest use md5(uniqid(time())), you have encoded the message part in addition to encoded file with $body .= chunk_split(base64_encode($message)), this is not necessary since you are sending plain text, pay attention to terminate properly your mime boundary because if used in the wrong sequence may cause incorrect attachment of files to your mail.

There are some other minor fix to apply, you can find them into my code.

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!");
}

There is no reason for unlink($name) since you are not uploading files to your server, you are reading the tmp file name from tmp server directory and converting it in base64 (nothing else...), you miss the final "--$boundary--"; very important to terminate properly the message part and the attachments... $headers .= "boundary = $boundary... is not correct because needs a tabulation instead you can write it like $headers .= " Boundary = $boundary...

I did a test using my code and with success, I censored my sensible data, all rest is visible and Ok:

From - Mon Jun  3 18:17:49 2019
Return-Path: <test@test.com>
Delivered-To: test@test.com
    for <test@test.com>; Mon, 03 Jun 2019 18:17:36 +0200
    ; Mon, 03 Jun 2019 18:17:36 +0200
Date: Mon, 03 Jun 2019 18:17:39 +0200
To: test@test.com
Subject: =?UTF-8?B?UHJvdmE=?=
From: =?UTF-8?B?QWxlc3NhbmRybyBNYXJpbnV6emk=?= <test@test.com>
Reply-To: =?UTF-8?B?QWxlc3NhbmRybyBNYXJpbnV6emk=?= <test@test.com>
Return-Path: test@test.com
MIME-Version: 1.0
Content-Type: multipart/mixed;
 Boundary="==Multipart_Boundary_x2bf07da61d9de3d12f7c30d38eabbf40x"

This is a multi-part message in MIME format.

--==Multipart_Boundary_x2bf07da61d9de3d12f7c30d38eabbf40x
Content-Type: text/plain; Charset="UTF-8"
Content-Transfer-Encoding: 8bit

Test with attachments...

--==Multipart_Boundary_x2bf07da61d9de3d12f7c30d38eabbf40x
Content-Type: application/octet-stream; Name="test.zip"
Content-Disposition: attachment; Filename="test.zip"
Content-Transfer-Encoding: base64

UEsDBBQAAAAIAImAwU7q5x4NDgAAAA4AAAAIAAAAdGVzdC50eHQrycgsVgCiRIWS1OISAFBLAQIf
ABQAAAAIAImAwU7q5x4NDgAAAA4AAAAIACQAAAAAAAAAIAAAAAAAAAB0ZXN0LnR4dAoAIAAAAAAA
AQAYALUw9eeCGNUBtTD154IY1QEfNnDlghjVAVBLBQYAAAAAAQABAFoAAAA0AAAAAAA=


--==Multipart_Boundary_x2bf07da61d9de3d12f7c30d38eabbf40x
Content-Type: application/octet-stream; Name="this is another test.zip"
Content-Disposition: attachment; Filename="this is another test.zip"
Content-Transfer-Encoding: base64

UEsDBAoAAAAAALuRw04AAAAAAAAAAAAAAAAYAAAAdGhpcyBpcyBhbm90aGVyIHRlc3QudHh0UEsB
Ah8ACgAAAAAAu5HDTgAAAAAAAAAAAAAAABgAJAAAAAAAAAAgAAAAAAAAAHRoaXMgaXMgYW5vdGhl
ciB0ZXN0LnR4dAoAIAAAAAAAAQAYADFJ3FcnGtUBMUncVyca1QExSdxXJxrVAVBLBQYAAAAAAQAB
AGoAAAA2AAAAAAA=


--==Multipart_Boundary_x2bf07da61d9de3d12f7c30d38eabbf40x--
halfer
  • 19,824
  • 17
  • 99
  • 186
Alessandro
  • 900
  • 12
  • 23