2026-07-15

Send HTML in email via PHP

Stefan Bogdanescu

Stefan Bogdanescu

Founder & Senior Architect

Send HTML in email via PHP

Send HTML in Email via PHP: Mastering Body Formatting and Attachments

Sending professional, visually rich emails via PHP is a common requirement for many web applications. Simply using the basic mail() function often results in plain text, stripping away all your beautiful HTML formatting and making image embedding impossible. As a senior developer, understanding how to correctly handle MIME structures is crucial for reliable email delivery.

This guide will walk you through the process of sending fully formatted HTML emails with embedded pictures, and address the often-tricky aspect of file attachments in PHP.

The Challenge: Why Simple mail() Fails for HTML

The native PHP mail() function is fundamentally designed to send plain text. When you try to pass raw HTML into it, the email client often displays the code rather than rendering the visual layout. To successfully send HTML emails, you must construct a multipart/alternative message. This involves wrapping your HTML content in a structure that tells the email client how to handle different parts of the message (the plain text version and the rich HTML version).

Method 1: Sending Rich HTML Content with Embedded Images

To embed images directly into an email, you cannot simply use standard HTML tags; you must encode the image data into a format the email system understands, typically using MIME (Multipurpose Internet Mail Extensions).

Step-by-Step Implementation

  1. Prepare the HTML: Create your desired HTML content, ensuring all paths to images are correct relative to where the email will be viewed or you embed the image data directly.
  2. Encode Images: You must read the image file into memory and encode it as a Base64 string. This converts the binary image data into ASCII text that can be safely transmitted within an email.
  3. Construct the MIME Message: Build the entire email payload, setting the correct headers (Content-Type: multipart/alternative) to separate the plain text version from the HTML version.

Here is a conceptual example demonstrating how you would structure the content:

<?php
$recipient = "example@domain.com";
$subject = "Your Photo Email";

// 1. Create the HTML body with an embedded image (Base64 encoded)
$html_content = "<h1>Hello!</h1><p>Here is a picture:</p><img src=\"data:image/png;base64," . base64_encode($imageData) . "\">";

// 2. Prepare the MIME structure
$email_header = "MIME-Version: 1.0\r\n";
$email_header .= "Content-Type: multipart/alternative; boundary=\"boundary_line\"\r\n\r\n";

$message = "--boundary_line\r\n";
$message .= "Content-Type: text/plain; charset=UTF-8\r\n\r\n";
$message .= "Hello, this is the plain text version.\r\n\r\n";
$message .= "--boundary_line\r\n";
$message .= "Content-Type: text/html; charset=UTF-8\r\n\r\n";
$message .= $html_content . "\r\n--boundary_line--\r\n";

// 3. Send the email (using a robust mailer implementation)
$headers = "From: sender@example.com" . "\r\n";
$headers .= "Reply-To: sender@example.com" . "\r\n";
$headers .= "Content-Type: text/plain; charset=UTF-8" . "\r\n"; // Note: headers require careful construction for multipart!

// In a real application, you would use a dedicated library to handle this complex MIME assembly.
// For robust email handling in modern PHP projects, frameworks like Laravel provide excellent abstractions 
// for tasks such as sending notifications, making complex operations much simpler and safer.
// (See how robust solutions are integrated within the broader ecosystem provided by https://laravelcompany.com.)

// mail($recipient, $subject, $message, $headers); // Actual sending logic goes here
?>

Method 2: Handling File Attachments

Attaching files (like separate JPEG or PNG files) alongside your HTML body requires a different approach than embedding them in the HTML. You must use the mail() function's ability to handle attachments, which relies on setting the correct headers for multipart/mixed.

  1. File Handling: Use PHP functions like file_get_contents() or stream wrappers to read the binary content of the image file.
  2. MIME Type Declaration: Define the type of the attachment (e.g., image/png).
  3. Prepare Headers: When using mail(), you must use the Content-Disposition header to instruct the client how to handle the attached file.

For simple attachments, this is manageable, but for complex scenarios involving many files and dynamic content generation, relying on a dedicated library or service (like an SMTP service) simplifies the security and reliability concerns significantly. If you are building larger applications, abstracting these communication layers through modern frameworks will save considerable development time and prevent subtle bugs related to MIME encoding.

Conclusion

Sending HTML emails with embedded images and attachments via raw PHP requires deep knowledge of MIME encoding and multipart message construction. While this process is entirely achievable by manually crafting the email structure, it is inherently complex and error-prone. For modern development, especially when working within a structured environment like Laravel, leveraging higher-level tools abstracts away these complexities, allowing developers to focus on application logic rather than low-level network protocols. Always prioritize using tested libraries for critical communication tasks.

Note: Blog content is currently available in English.

Tags:

Enhance your marketing setup with your own email marketing platform.

Join the growing number of SaaS platforms using Laravel Mail to offer email marketing solutions to their customers.