How to attach PDF to email using PHP mail function
Stefan Bogdanescu
Founder & Senior Architect
How to Attach PDF Files to Emails Using PHP Mail Function: A Developer's Guide
Sending emails is a fundamental task in web development, and while the basic PHP mail() function is straightforward for sending plain text messages, adding file attachments—especially binary files like PDFs—introduces a layer of complexity. Many developers run into issues when trying to attach files using the simplest syntax.
If you are attempting to attach a PDF via the basic $headers method, you will likely encounter errors or corrupted attachments because the standard mail() function doesn't natively handle the complex MIME (Multipurpose Internet Mail Extensions) structure required for file attachments.
This guide will walk you through the correct, developer-focused way to package your content and PDF into a proper MIME email so that it attaches reliably across various mail servers.
The Limitation of Basic mail()
The simple implementation shown in your example:
$headers = "From:" . $from;
mail($to,$subject,$message,$headers);
...only sends plain text. To attach a file, you need to construct a multipart email. This means structuring the entire email as a container that holds multiple parts (the body, headers, and the attachment). The standard mail() function is often too simplistic for this advanced task, forcing us to manually construct the raw email content.
The Solution: Constructing a Multipart Email
To successfully attach a PDF, we must manually build the raw email message string, ensuring that the file data is encoded correctly as a separate part of the message, properly formatted with MIME headers.
The most robust way to handle this in PHP is to use mail() but feed it the complete, correctly structured body, including the attachment data encoded in Base64.
Step-by-Step Implementation
Here is a comprehensive example demonstrating how to read a PDF file and attach it to an email using PHP:
<?php
// --- Configuration ---
$to = "me@myemail.com";
$subject = "Report with PDF Attachment";
$from = "Jane Doe <janedoe@myemail.com>";
$pdf_path = "/path/to/your/document.pdf"; // IMPORTANT: Ensure this file exists
// 1. Read the PDF file in binary mode
if (!file_exists($pdf_path)) {
die("Error: PDF file not found at $pdf_path");
}
$pdf_content = file_get_contents($pdf_path);
// 2. Encode the PDF content into Base64 for safe transmission
$pdf_data = base64_encode($pdf_content);
// 3. Construct the MIME Headers and Body
$email_body = "Hello,\n\nAttached is the requested document.\n\nBest Regards,\nJane Doe";
// Create the full structure using MIME standards for attachments
$mime_headers = "From:{$from}\r\n";
$mime_headers .= "To:{$to}\r\n";
$mime_headers .= "Subject:{$subject}\r\n";
$mime_headers .= "MIME-Version: 1.0\r\n";
$mime_headers .= "Content-Type: multipart/mixed; boundary=\"----=_boundary_1234567890\"\r\n\r\n";
// Define the boundary string used to separate the parts
$boundary = "----=_boundary_1234567890";
// Construct the full multi-part email structure
$full_email = "--{$boundary}\r\n";
$full_email .= "Content-Type: text/plain; charset=UTF-8\r\n";
$full_email .= "Content-Disposition: attachment; filename=\"document.pdf\"\r\n\r\n";
$full_email .= $email_body . "\r\n";
$full_email .= "--{$boundary}--" . "\r\n";
// Append the Base64 encoded file data part
$full_email .= "\r\n--{$boundary}\r\n";
$full_email .= "Content-Type: application/pdf; name=\"document.pdf\"\r\n";
$full_email .= "Content-Disposition: attachment; filename=\"document.pdf\"; filename=\"document.pdf\"\r\n";
$full_email .= "Content-Transfer-Encoding: base64\r\n\r\n";
$full_email .= $pdf_data . "\r\n";
// 4. Send the email using the constructed raw content
// Note: We use the mail() function, passing the entire MIME structure as the message body.
$success = mail($to, $subject, $full_email);
if ($success) {
echo "Mail successfully sent with PDF attachment!";
} else {
echo "Error: Failed to send the email.";
}
?>
Best Practices and Modern Alternatives
While manually constructing MIME parts works for simple scenarios, it is often tedious and error-prone. As you grow your application, relying on lower-level functions like mail() for complex tasks can become a maintenance headache.
For modern, enterprise-level applications, especially when building robust communication systems, developers often turn to established libraries or frameworks that handle this complexity automatically. For instance, if you are building an API layer, understanding how data serialization and transmission work is crucial—concepts similar to those employed by the principles discussed on platforms like laravelcompany.com.
For production environments, consider using dedicated third-party libraries or services (like SendGrid, Mailgun, or Amazon SES) which are optimized for reliable email delivery and attachment handling, abstracting away the complexities of raw MIME construction. This approach ensures better error logging, security, and scalability compared to relying solely on native PHP functions for complex tasks.
Conclusion
Attaching files to emails using raw PHP functions requires a deep understanding of MIME standards. By manually constructing the multipart/mixed structure and encoding binary data using Base64, you can successfully instruct the mail server how to handle your PDF attachment. While this method provides granular control, for large-scale projects, leveraging higher-level libraries or dedicated email services is the more practical and secure path forward.