Jump to content

How to send html formatted email with attachment


wezken

Recommended Posts

Hello. I have created a php webpage which I can use to send an email around the group of musicians that I administer. The message part of the email is html so that I can structure it in certain ways, like bulleted lists, or making certain parts bold so they stand out.

I need to be able to attach files from time to time and I have found out how to do that successfully, but I cant see how to have html formatted text and attach a file at the same time.  I guess it might be something to do with '$headers .= "Content-type:text/mixed;charset=UTF-8" . "\r\n";'  but if I change 'mixed' to 'html' I get the html formatting but it doesn't attach the file.  I have given my code below.  The way it works is that when the form is submitted, the code looks to see if a file attachment has been selected. If not, an error is thrown and that directs the code to the part that only sends the html email.  If an attachment has been selected, there is no error and the code sends the email with the attachment, however the message is sent in plain text.   I would be grateful if someone could point out what I am doing wrong.

if(isset($_POST['button'])) {

    $from_email         = 'website@falnamusic.com'; //from mail, sender email address
    $recipient_email = 'wes@falnamusic.com'; //recipient email address
     
    //Load POST data from HTML form
    //$sender_name = $_POST["sender_name"]; //sender name
    //$reply_to_email = $_POST["sender_email"]; //sender email, it will be used in "reply-to" header
    $subject     = $_POST["subjectfield"]; //subject for the email
    $message     = $_POST["messagefield"]; //body of the email
     // Email body content                                                                                                //nl2br interprets line breaks
    $htmlContent = "<font face='Verdana' size='2' color='black'>" . $salutation . nl2br($_POST["messagefield"]) . "<font face='Arial' size='1' color='BLACK'><p>To reply use the Reply button</p> "; 

    //Get uploaded file data using $_FILES array
    $tmp_name = $_FILES['attachment']['tmp_name']; // get the temporary file name of the file on the server
    $name     = $_FILES['attachment']['name']; // get the name of the file
    $size     = $_FILES['attachment']['size']; // get size of the file for size validation
    $type     = $_FILES['attachment']['type']; // get type of the file
    $error     = $_FILES['attachment']['error']; // get the error (if any)
 
    //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"); // set the file handle only for reading the file
    $content = fread($handle, $size); // reading the file
    fclose($handle);                 // close upon completion
 
    $encoded_content = chunk_split(base64_encode($content));
    $boundary = md5("random"); // define boundary with a md5 hashed value
 
    //header
    $mime_boundary = 'Multipart_Boundary_x'.md5(time()).'x';
    $headers = "MIME-Version: 1.0\r\n"; // Defining the MIME version
    $headers .= "Content-type:text/html;charset=UTF-8" . "\r\n";
    $headers .= "From:".$from_email."\r\n"; // Sender Email
    $headers .= "Reply-To: ".$reply_to_email."\r\n"; // Email address to reach back
    $headers .= "Content-Type: multipart/mixed;"; // Defining Content-Type
    $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: $type; name=".$name."\r\n";
    $body .="Content-Disposition: attachment; filename=".$name."\r\n";
    $body .="Content-Transfer-Encoding: base64\r\n";
    $body .="X-Attachment-Id: ".rand(1000, 99999)."\r\n\r\n";
    $body .= $encoded_content; // Attaching the encoded file with email

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

    }else{
    
    //header
    $headers = "MIME-Version: 1.0" . "\r\n";
    $headers .= "Content-type:text/html;charset=UTF-8" . "\r\n";

    // More headers
    $headers .= "From:".$from_email."\r\n"; // Sender Email
    $headers .= "Message:" . $message ."\r\n";    

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

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

Link to comment
Share on other sites

Don't try and do this manually, use a library such as PHPMailer or Symfony Mailer.  There are a lot of specific formatting rules you need to follow for doing proper mime emails and it's not worth the time and effort to try and figure it all out yourself when libraries such as those can handle it all for you in an easy to use interface.

For example, with Symfony mailer you would have code like this (using SMTP):

    $dsn = 'tls://smtp.example.com:587/';
    $mailer = new Mailer((new EsmtpTransportFactory())->create($dsn));

    //Create a new email object.
    $email = new \Symfony\Component\Mime\Email();
    $email->from($from);  //Set the from address

    //If $from is not an address you control, set the return path to one you do.
    //$email->returnPath('system@example.com');

    $email->to($to); //Set recipient.
    if ($cc){
        $email->cc($cc); //If you need to CC someone
    }
    if ($bcc){
        $email->bcc($bcc); //If you need to BCC someone.
    }
    $email->subject($subject);  //Subject line
    $email->html($message); //HTML Body
    //$email->text($message); //Plain-text alternative if you have one, or don't want HTML.
    if ($attachment['error'] === UPLOAD_ERR_OK){
        //Attach uploaded file.
        $email->attachFromPath($attachment['tmp_name'], $attachment['name'], $attachment['type']);
    }

    //Send email
    $mailer->send($email);

 

Link to comment
Share on other sites

Thanks for your replies, and ginerjm I will take your error reporting suggestion in future, saves constantly having to open the error.log file !

Actually I already tried PHP Mailer but my web host instantly objected, saying it was a code injection frailty or some such thing, so I had to remove it.

The thing is, I'm so close. I can send an email with an attachment successfully with my code, it's just that it ignores any html formatting.  Whereas if I send an email without an attachment the html is acted on.  I just hoped that one of you php experts might spot something in my code which is causing this behaviour.

Link to comment
Share on other sites

I haven't not used PHPMailer in quite some time (it really is worth checking with your provider - if they say no, get a new provider) but perhaps if you comment out the Content-Type set under the comment //plain text in the attachment branch of your if/else it won't reset the content-type from text/html to text/plain as it's being asked to do.

Specifically, this line:

$body .= "Content-Type: text/plain; charset=ISO-8859-1\r\n";

It may do nothing as it's assigned to the body instead of the headers, but it's the only place that specifically assigns the content-type to plaintext, and it only happens when there's an attachment so it sounds like it's a good place to start.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.