user7767366
user7767366

Reputation:

php - mail with attachment file - message encrypted

I wrote this code for send an email with attachment in php from an html format:

<?php

if($_POST && isset($_FILES['file-upload'])){

    $from             = $_POST["email"]; 
    $rubinetteria     = '[email protected]'; 

    $nome             = filter_var($_POST["nome"], FILTER_SANITIZE_STRING); 
    $email            = filter_var($_POST["email"], FILTER_SANITIZE_STRING); 
    $oggetto          = filter_var($_POST["oggetto"], FILTER_SANITIZE_STRING); 
    $compagnia        = filter_var($_POST["company"], FILTER_SANITIZE_STRING);
    $ruolo            = filter_var($_POST["ruolo"], FILTER_SANITIZE_STRING);
    $messaggio        = filter_var($_POST["messaggio"], FILTER_SANITIZE_STRING); 

    $fileTmpName     = $_FILES['file-upload']['uploads'];
    $fileName        = $_FILES['file-upload']['name'];
    $fileSize        = $_FILES['file-upload']['size'];
    $fileType        = $_FILES['file-upload']['type'];
    $fileError       = $_FILES['file-upload']['error'];




    $handle = fopen($fileTmpName, "r");
    $content = fread($handle, $fileSize);
    fclose($handle);
    $encoded_content = chunk_split(base64_encode($content));

        $boundary = md5("sanwebe");

        $headers = "MIME-Version: 1.0\r\n";
        $headers .= "From:".$compagnia."\r\n";
        $headers .= "Reply-To: ".$reply_to_email."" . "\r\n";
        $headers .= "Content-Type: multipart/mixed; boundary = $boundary\r\n\r\n";


        $body = "--$boundary\r\n";
        $body .= "Content-Type: text/html; charset=ISO-8859-1\r\n";
        $body .= "Content-Transfer-Encoding: base64\r\n\r\n";
        $body .= "<b>Azienda: </b>" .$compagnia. "<br>";
        $body .= "<b>Nome e Cognome: </b>" .$nome. "<br>";
        $body .= "<b>Ruolo: </b>" .$ruolo. "<br>";
        $body .= "<br>". chunk_split(base64_encode($messaggio));


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

    $sentMail = @mail($rubinetteria, $oggetto, $body, $headers);

}


?>

The problem is that when I receive the e-mail, some of the message is encrypted. I guess the problem is this line of code:

$body .= "<br>". chunk_split(base64_encode($messaggio));

I tried to subscribe this line with this one:

$body .= "<br>".$messaggio;

But in this case the message is not encrypted but there is no attachment file (the description confirms that the attachment is actually processed but not received)

Upvotes: 0

Views: 678

Answers (1)

Martin
Martin

Reputation: 22760

You have two issues

1)

 $fileTmpName     = $_FILES['file-upload']['uploads'];

This is incorrect, the $_FILES value you are referencing should be the temporary location of the uploaded file, that is not [uploads] but [tmp_name], so replace the above code with:

 $fileTmpName     = $_FILES['file-upload']['tmp_name'];

2)

The second issue is the size of the file you've given to PHP to read $fileSize is not the full file, so the attachment is truncated and therefore displays improperly (appearing "encrypted").

I've noticed PHP has numerous issues with the way it counts file sizes [possibly on certain platforms, I don't know]. In this instance it seems like the value given to the fread function is not the same byte-count as the actual complete file size, so the mail function only loads ~99% of the attachment, meaning the file is incomplete and so will look garbled ("encrypted").

As stated on the manual page:

If you just want to get the contents of a file into a string, use file_get_contents() as it has much better performance [than fread()].

so replace $handle = fopen($fileTmpName, "r");
$content = fread($handle, $fileSize); with:

 $content = file_get_contents($fileTmpName); 

And this will catch the whole file size, rather than the arbitary amount defined by $fileSize.
You should now have the complete file uploaded in your email.


Bonus:

As noted by nogad, you really should look up using Swift Mailer or PHPMailer as mail function is fraught with similar little issues like the one here.

Upvotes: 2

Related Questions