Send Email with Attachment in PHP

Sending emails from the script is a very useful functionality in the web application. Most of the websites used the email sending feature to send notifications to the user. If your web application is developed with PHP or uses PHP, it’s very easy to send emails from the script using PHP.

PHP provides an easy way to send emails from the website. You can send text or HTML email with the mail() function in PHP. But sometimes email functionality needs to be extended to send an attachment with the email. Sending emails with attachments in PHP using the native mail() function requires manual handling of MIME types, encoding, and boundaries. In this tutorial, you’ll learn exactly how to send email with attachment in PHP using a working example.

In this tutorial, we will show you how to send an email with an attachment using the PHP mail() function. We will also cover how to send HTML emails with attachments (any file type, such as images, documents, and PDFs) and how to send emails to multiple recipients.

🚀 Prerequisites

Before you can use the code in this tutorial, make sure you have the following:

  • A web server with PHP installed.
  • mail() function is enabled on your server
  • You have a file ready to attach (PDF, image, etc.)

How to Send Email with Attachment in PHP

To send an email with an attachment in PHP, you need to set the appropriate headers and encode the attachment file in a format that can be sent via email. The following example demonstrates how to send an email with a PDF attachment using the mail() function in PHP.
Here are the key steps involved in the process:

  • Define Email Configuration (these variables control who receives the email and who sends it): The $to variable is the recipient’s email address, $formName is the name that will appear in the “From” field of the email, and $formEmail is the email address that will appear in the “From” field.
  • Create HTML Email Body: You can send a rich HTML email instead of plain text. Using HTML improves readability and user experience. The $messageHtml variable contains the HTML content of the email. You can customize this HTML to include your desired message, formatting, and styling.
  • Attach a File and Encode the Attachment: The $attachmentPath variable specifies the path to the file you want to attach. The script reads the file content, encodes it in base64 format, and prepares it for sending as an email attachment.
  • Create a Unique Boundary: Boundary separates different parts of the email. The $boundary variable is generated using the md5 hash of the current time to ensure uniqueness. This boundary is used in the email headers and body to indicate where the HTML content ends and the attachment begins.
  • Set Email Headers: The script sets the necessary email headers, including “From”, “Reply-To”, “MIME-Version”, and “Content-Type”. The “Content-Type” header specifies that the email is multipart/mixed and includes the boundary string.
  • Construct the Email Body: The email body is constructed in a multipart format. It includes the HTML content followed by the attachment. Each part is separated by the boundary string defined earlier.
  • Send the Email: Finally, the mail() function is called with the recipient’s email address, subject, email body, and headers. The script checks if the email was sent successfully and outputs an appropriate message.
<?php 
// Configuration - change these values as needed
$to      'recipient@example.com';
$formName 'Demo Site';
$formEmail 'sender@example.com';

// Subject of the email
$subject 'Test email with attachment (PHP mail())';

// HTML message body
$messageHtml = <<<HTML
<html>
<head>
  <title>Test Email</title>
</head>
<body>
  <h1>PHP mail() with attachment</h1>
  <p>This is an <strong>HTML</strong> email body.</p>
  <p>Regards,<br>PHP Script</p>
</body>
</html>
HTML;

// Attachment file path (local)
$attachmentPath __DIR__ '/sample-attachment.pdf';

$fileSize filesize($attachmentPath);
$handle   fopen($attachmentPath'rb');
$content  fread($handle$fileSize);
fclose($handle);
$encodedContent chunk_split(base64_encode($content));

$boundary md5(time());

// Headers
$headers = [];
$headers[] = 'From: ' $formName ' <' $formEmail '>';
$headers[] = 'Reply-To: ' $formEmail;
$headers[] = 'MIME-Version: 1.0';
$headers[] = "Content-Type: multipart/mixed; boundary=\"{$boundary}\"";

// Multipart body (HTML only)
$body "--{$boundary}\r\n";
$body .= "Content-Type: text/html; charset=UTF-8\r\n";
$body .= "Content-Transfer-Encoding: 7bit\r\n\r\n";
$body .= $messageHtml "\r\n\r\n";

// Attachment part
$body .= "--{$boundary}\r\n";
$body .= "Content-Type: application/octet-stream; name=\"".basename($attachmentPath)."\"\r\n";
$body .= "Content-Transfer-Encoding: base64\r\n";
$body .= "Content-Disposition: attachment; filename=\"".basename($attachmentPath)."\"\r\n\r\n";
$body .= $encodedContent "\r\n";

// End of mixed boundary
$body .= "--{$boundary}--";

// Send mail
$sent mail($to$subject$bodyimplode("\r\n"$headers));

if (
$sent) {
    echo 
"Email successfully sent to {$to}\n";
} else {
    echo 
"Failed to send email to {$to}\n";
}
?>

Send Email to Multiple Recipients:
You can send emails to multiple recipients by separating their email addresses with commas in the $to variable. For example:

$to 'user@example.com, anotheruser@example.com';

The Cc and Bcc fields can also be added to the email headers to send copies of the email to additional recipients without revealing their email addresses to others.

$headers[] = 'Cc: cc@example.com'; 
$headers[] = 'Bcc: bcc@example.com';

Send Email with Multiple Attachments:
The above example demonstrates how to send an email with a single attachment. If you want to send an email with multiple attachments, you can repeat the attachment part in the email body for each file you want to attach. Each attachment should be separated by the same boundary string.

Here is a separate tutorial that explains how to send an email with multiple attachments in PHP:

⚠️ Important Notes (Very Important for Production)

  • mail() is not recommended for production use, especially with attachments, due to reliability and security issues.
  • For production, consider using SMTP libraries like PHPMailer or SwiftMailer, which provide better handling of email sending, including attachments, and support for authentication and encryption.

Here is a tutorial that explains how to send email via SMTP server in PHP using PHPMailer:

🛠️ Common Issues & Fixes

1. Email Not Sending on Localhost:

  • Configure SMTP in php.ini
  • Use tools like MailHog or sendmail

2. Attachment Corrupted:

  • Ensure proper Base64 encoding
  • Do not miss chunk_split()

3. Email Goes to Spam:

  • Use valid “From” email
  • Add SPF/DKIM records
  • Avoid spammy content

🎯 Final Thoughts

Sending emails with attachments in PHP is a common requirement for many web applications. Here we have provided the easiest way to send email with attachment in PHP. You don’t need to include any library to send HTML email with attachments. Using the PHP default mail() function you can easily send email with pdf/image attachment. This method gives you full control over email structure, but also requires careful handling of MIME formatting.
While the default mail() function can handle basic email sending, it has limitations when it comes to attachments and reliability. For production environments, it’s recommended to use dedicated libraries like PHPMailer or SwiftMailer to ensure better performance and security. If you’re building a real-world application, switching to a mailing library will save you time and prevent delivery issues.

Looking for expert assistance to implement or extend this script’s functionality? Submit a Service Request

20 Comments

  1. Ottavino Gnata Said...
  2. Alcides Said...
  3. Ed Said...
  4. Ali Said...
  5. Val Said...
  6. Mehul Said...
  7. Usman Mustafa Khawar Said...
  8. Emanuele Said...
  9. Hans Rondon Said...
  10. Ivan Said...
  11. Umesh Computer Said...
  12. Christoph Said...
  13. Sukhdeep Kaur Said...
  14. Jithin S Said...
  15. Gyula Said...
  16. Benjamin Said...
    • CodexWorld Said...
  17. Sachin Said...
  18. Jason Morita Said...

Leave a reply

construction Need this implemented in your project? Request Implementation Help → keyboard_double_arrow_up