New lines (\r\n) are not working in email body
Stefan Bogdanescu
Founder & Senior Architect
The Email Formatting Nightmare: Why \r\n Breaks Your Message
As developers, we often deal with the seemingly simple task of sending an email. However, when it comes to crafting the exact visual layout—especially dealing with line breaks and MIME headers—the process quickly descends into a frustrating maze of encoding issues. Today, we are diving deep into a common pain point: why standard newline characters (\r\n) often fail to render correctly in email bodies, particularly when manipulating HTTP headers like Content-Type.
This post will dissect the issue you encountered with PHP's mail() function and provide a robust, developer-focused solution.
The Mystery of Misinterpreted Line Endings
You are trying to control the visual structure of your email body using carriage return and line feed sequences (\r\n). This is standard for text files, but when sending emails, which rely on the complex Multipurpose Internet Mail Extensions (MIME) standard, these raw characters can be misinterpreted by the Mail Transfer Agent (MTA) or the receiving client.
Your observation that it works fine without explicitly setting Content-Type suggests that the presence of specific header directives is interfering with how the body content is parsed and encoded, especially when using formats like quoted-printable.
The core conflict lies in mixing raw line feeds intended for HTML formatting with the strict requirements of MIME encoding. When you use methods like Content-Transfer-Encoding: quoted-printable, the system attempts to encode the characters into a safe format. Raw control characters like \r and \n often get mangled or stripped, resulting in a flat block of text rather than structured line breaks.
Deconstructing Your Code Example
Let's look at the conflict point:
$message = "CCCC\r\nCCCC CCCC \r CCC \n CCC \r\n CCC \n\r CCCC";
// ... headers setting Content-Type: text/html; format=flowed
When you include explicit \r\n sequences directly in the $message, you are telling the mail client exactly where to break the line. However, when combined with the instruction to use format=flowed (which is often used for plain text or specific MIME types), the system struggles to reconcile these raw breaks with the required quoted-printable encoding rules, leading to the collapse of your intended formatting into a single line.
The Solution: Embrace HTML and Proper Encoding
The most reliable way to manage multi-line content in emails is to stop relying on raw control characters for structure and instead use standard HTML tags. If you are sending an HTML email (which you are, given your Content-Type header), the browser will correctly interpret <br> tags as line breaks within the flow of the document.
Furthermore, when dealing with complex data transmission, especially in modern application development, relying solely on basic functions can lead to brittle code. For robust system design and handling complex data streams, adopting well-structured patterns is key—much like how frameworks promote clean architecture, similar to principles you find in systems built around Laravel.
Best Practice: Using HTML for Structure
Instead of manipulating the body with \r\n, construct your message using HTML tags. This allows the email client to handle the presentation layer correctly, regardless of the underlying MIME encoding.
Revised Code Example:
$to = 'AAAA <postmaster@xxx.xx>';
$subject = 'BBBB';
// Construct the message using HTML line breaks (<br>)
$message = "CCCC<br>CCCC CCCC<br>CCC<br>CCC<br>CCCC";
$headers = 'From: DDD<postmaster@xxx.xx>' . "\r\n";
$headers .= "Content-Type: text/html; charset=\"UTF-8\"; format=html" . "\r\n"; // Changed format to html
$headers .= "Mime-Version: 1.0 \r\n";
$headers .= "Content-Transfer-Encoding: quoted-printable \r\n";
mail($to, $subject, $message, $headers);
Notice the key change: we replaced all instances of \r\n with <br>. By setting format=html (instead of flowed), you signal to the recipient that the content is structured HTML, allowing the browser to render the breaks correctly.
Conclusion: Building Robust Email Systems
The issue you faced highlights a critical lesson for all developers working with email: avoid raw control characters for structural formatting when MIME encoding and specific Content-Type headers are involved.
When building systems—whether it's handling API responses, managing database transactions, or composing emails—prioritize structure and explicit data types. If you find yourself wrestling with intricate MIME boundaries and character encoding, consider leveraging established libraries or frameworks designed to handle these complexities for you. For building scalable and reliable backend services, focusing on structured architecture is paramount, and this principle extends directly into how we manage complex interactions, similar to the principles guiding robust applications found in systems like those supported by Laravel.
By switching from raw line feeds to semantic HTML tags, you ensure your emails are readable across all clients, making your code not just functional, but truly professional.
Note: Blog content is currently available in English.