Email with attachment in PHP

Send file with the mail function.

Sending an email with PHP is quite easy thanks to the mail function. Things become more difficult if you want to attach a file.

The body of the email must respect a specific structure with blocs delimited by boundaries. We need two different kinds of boundaries. The first one to separate the message from the attachment. The second one for the alternatives of the message: plain text or HTML

Send a file by email with PHP

<?php $to = ''; $from = ''; $subject = 'Email with file'; $messageHhtml = '<b>The message in HTML</b>'; $fileContent = 'Content of the file.'; $boundaryStructure = md5(rand()); $boundaryAlternatives = md5(rand()); $headers = [ "From: $from", "Reply-To: $from", "Content-Type: multipart/mixed; boundary="$boundaryStructure"" ]; /* Encoding of the file to send, according to the RFC 2045. */ $attachment = chunk_split(base64_encode($fileContent)); /* * The best way to do it would be to externalize the following part in a template file. * For the example an ob_start is easier to understand. */ ob_start(); ?> --<?=$boundaryStructure . PHP_EOL /* First part of the structure: le message */?> Content-Type: multipart/alternative; boundary="<?=$boundaryAlternatives?>" --<?=$boundaryAlternatives . PHP_EOL /* First alternative: plain text */?> Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 8bit <?=strip_tags($messageHtml)?> --<?=$boundaryAlternatives . PHP_EOL /* Second alternative: HTML */?> Content-Type: text/html; charset="utf-8" Content-Transfer-Encoding: 8bit <?=$messageHtml?> --<?=$boundaryAlternatives /* End of alternatives */?>-- --<?=$boundaryStructure . PHP_EOL /* Second part of the structure: the file */?> Content-Type: text/csv; name="filename.csv" Content-Transfer-Encoding: base64 Content-Disposition: attachment <?=$attachment?> --<?=$boundaryStructure /* End the structure */?>-- <?php $message = ob_get_clean(); $isMailSent = mail($to, $subject, $message, implode(PHP_EOL, $headers));