How to send correct UTF-8 mail in PHP
Here is a simple UTF-8 mail sender function. This function also encode subject and plain-text message to UTF-8. If you need HTML mail sender, change the code in line 4 from text/plain to text/html, but this function is usable the most cases without any modification. I've used this function for webform and other web based mail notification.
<?php function mail_utf8($to, $subject = '(No subject)', $message = '', $header = '') { $header_ = 'MIME-Version: 1.0' . "\r\n" . 'Content-type: text/plain; charset=UTF-8' . "\r\n"; mail($to, '=?UTF-8?B?'.base64_encode($subject).'?=', $message, $header_ . $header); } ?>
You can copy & paste or download it:
mail_utf8.php [274 byte]







My message was good, except for the subject, that showed strange characters. Your code helped me solve this.
- reply
Submitted by flashfs (not verified) on December 9, 2010 - 2:38pm.Thanks! This code is simply great! Cudos to the author.
- reply
Submitted by Drugelis (not verified) on October 5, 2010 - 1:04pm.Those f*** "È" (Italian) in my subjects were productivity sinkholes.... thanks for your tip!
- reply
Submitted by Zane (not verified) on September 8, 2010 - 11:53pm.Great. But body of email still broken
- reply
Submitted by venoel (not verified) on July 18, 2010 - 7:03pm.Hallo,
I have code like this how can i put that:
$sendTo = "wiyono4@msn.com";
$subject = "hm-wortart Website kontakt";
$headers = "From: " . $_POST["vorname"] ." ". $_POST["nachname"] . "<" . $_POST["email"] .">";
$headers .= "nE-Mail: " . $_POST["email"];
$message .= "Name: " . $_POST["vorname"];
$message .= "\nName: " . $_POST["nachname"];
$message .= "\nE-Mail: " . $_POST["email"];
$message .= "\nBetreff: " . $_POST["subject"];
$message .= "\nMessage: " . $_POST["nachricht"];
mail($sendTo, $subject, $message, $headers);
echo ("Vielen Dank, Ihr Beitrag wurde gesendet!");
?>
Can you send me email, when you have solution?
Thank you so much..
- reply
Submitted by Wiyono (not verified) on July 9, 2010 - 8:16pm.I see you encode the subject only. Will it work also on the body content?
- reply
Submitted by Blutarsky (not verified) on July 6, 2010 - 11:08pm.Thanks alot!!
In the same way you can add UTF8 to sender name, receiver name, and subject, thanks!
- reply
Submitted by Victor Ocampo (not verified) on January 12, 2010 - 6:25pm.This seems to work okay when the email arrives in my GMail inbox, but when it arrives in my Outlook all the special characters are completely stripped out.
- reply
Submitted by Hotaka (not verified) on August 28, 2009 - 12:35am.Hi guys !
Im really new in php but I got a script that I want to work with utf-8.. Is there anybody who knows what I need to change in this code !? .. thanks and sorry for the noob question..
$contact_name = $_POST['name'];
$contact_company = $_POST['company'];
$contact_email = $_POST['email'];
$contact_country = $_POST['country'];
$contact_message = $_POST['message'];
if( $contact_name == true )
{
$sender = $contact_email;
$receiver = "info@domain.com";
$client_ip = $_SERVER['REMOTE_ADDR'];
$email_body = "Name: $contact_name \nEmail: $sender \n\nCompany: $contact_company \n\nMessage: \n\n$contact_message \n\nIP: $client_ip";
$email_body_auto_reply = "Dear $contact_name, \nWe will contact you within 24 hours, thanks. \n\nwww.domain.com";
$extra = "From: $sender\r\n" . "Reply-To: $sender \r\n";
$extra_auto_reply = "From: $receiver\r\n" . "Reply-To: $receiver \r\n";
mail( $sender, "Auto Reply from the KING", $email_body_auto_reply, $extra_auto_reply ); // auto reply mail to sender
if( mail( $receiver, "The KING", $email_body, $extra ) )
{
echo "success=yes";
}
else
{
echo "success=no";
}
}
?>
- reply
Submitted by TheKing (not verified) on August 25, 2009 - 12:42am.Thank you for the solution. It was very useful. My forum members were complaining about missing characters in the new reply notification emails.
- reply
Submitted by Pierrick (not verified) on July 30, 2009 - 11:16pm.Hi I tried your code but it doesn't show the utf8 code in the subject. Can you help. Thanks.
- reply
Submitted by Visitor (not verified) on July 15, 2009 - 12:17pm.It worked great for sending sweedish characters, thanks a million!
- reply
Submitted by Robin (not verified) on July 14, 2009 - 12:48pm.How did you come up with this solution? It worked GREAT!
- reply
Submitted by eliezer (not verified) on May 7, 2009 - 8:40pm.After 1.5 years from its posting it has served me well. Perfect soution for my Japanese Subject and From fields! Thank you so much!
- reply
Submitted by blackspot (not verified) on April 28, 2009 - 10:49am.Thanks!!
I've Googled several hours for solution for my (same) problem and your function helped.
Cheers from Croatia :)
- reply
Submitted by Hrvoje (not verified) on April 24, 2009 - 5:18pm.Exactly a year later, I found this information extremely useful. Solved my problem with strange characters in the FROM portion. Thanks!
- reply
Submitted by boediger (not verified) on February 15, 2009 - 8:46pm.To use this function instead of standard PHP's 'mail', you can modify function like this:
function mail_utf8($to, $subject = '(No subject)', $message = '', $header = '') {
$header_ = 'MIME-Version: 1.0' . "\r\n" . 'Content-type: text/plain; charset=UTF-8' . "\r\n";
$send_message=mail($to, '=?UTF-8?B?'.base64_encode($subject).'?=', $message, $header_ . $header);
if ($send_message) {
return true;
} else {
return false;
}
}
Then, in your main code you will be able to check if subroutine mail had sent the mail successfully.
Althogh, I'm not a pro in PHP, but it works for me ;)
- reply
Submitted by Visitor (not verified) on February 15, 2009 - 2:11am.Or just like this!:
<?php
function mail_utf8($to, $subject = '(No subject)', $message = '', $header = '') {
$header_ = 'MIME-Version: 1.0' . "\r\n" . 'Content-type: text/plain; charset=UTF-8' . "\r\n";
return mail($to, '=?UTF-8?B?'.base64_encode($subject).'?=', $message, $header_ . $header);
}
?>
(you dont have to first assign the result of mail to $send_message, and then check if $send_message is true (and if so return true) or false (and if so return false))
- reply
Submitted by Another Visitor (not verified) on September 18, 2009 - 1:05pm.Exactly a year later, I found this information extremely useful. Solved my problem with strange characters in the FROM portion. Thanks!
- reply
Submitted by Robbie (not verified) on December 22, 2008 - 5:13pm.You need a trailing "?=" after the base64-encoded string.
"=?UTF-8?B?".base64_encode($subject)."?="Best regards.
- reply
Submitted by reishi (not verified) on September 1, 2008 - 6:26pm.I've fixed it. Thank you!
- reply
Submitted by Thomas on September 27, 2008 - 2:01am.you need to fix it in the file as well
- reply
Submitted by Visitor (not verified) on January 21, 2009 - 10:42am.Thank you, your comment. I have fixed it also.
- reply
Submitted by Thomas on January 22, 2009 - 9:43am.Thank, nice piece of code,
But how do you encode the Headers "From:" field if it contains Unicode characters ?
- reply
Submitted by GiorgosK (not verified) on December 7, 2007 - 1:14pm.For the from field, like the subject, you have to base64_encode it !
Example :
And you can do the same for CC header !
Well done ;)
Best regards. Guillaume.
- reply
Submitted by Gwouite (not verified) on December 22, 2007 - 9:54pm.Hello I have the same problem. I have form from which you can send email with attachment. When I send it without attachment everything works but when I add one the headers are encoded correctly but the email is screwed. It arrives like so:
MIME-Version: 1.0
Content-Type: multipart/mixed;
boundary="==Multipart_Boundary_x6dd57d3a9e00235dcd8208baf5d169f9x"
This is a multi-part message in MIME format.
--==Multipart_Boundary_x6dd57d3a9e00235dcd8208baf5d169f9x
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: 8bit
Guru Pitka
Mariska Hargitay
--==Multipart_Boundary_x6dd57d3a9e00235dcd8208baf5d169f9x
Content-Type: image/jpeg;
name="=?utf-8?B?ZnJhdS3FocSbxI3FmcW+w73DocOtw6kuanBn?="
Content-Transfer-Encoding: base64
/9j/4AAQSkZJRgABAgAAZABkAAD//gASQWRvYmUgSW1hZ2VSZWFkef/sABFEdWNreQABAAQAAAA8
AAD/7gAOQWRvYmUAZMAAAAAB/9sAhAAGBAQEBQQGBQUGCQYFBgkLCAYGCAsMCgoLCgoMEAwMDAwM
DBAMDg8QDw4MExMUFBMTHBsbGxwfHx8fHx8fHx8fAQcHBw0MDRgQEBgaFREVGh8fHx8fHx8fHx8f
.....
My code is:
<?php // Read POST request params into global vars $to = $_POST['to']; $from = $_POST['from']; $subject = $_POST['subject']; $message = $_POST['message']; $subject = "=?utf-8?B?" . base64_encode($subject) . "?="; // Obtain file upload vars $fileatt = $_FILES['fileatt']['tmp_name']; $fileatt_type = $_FILES['fileatt']['type']; $fileatt_name = $_FILES['fileatt']['name']; $fileatt_name = "=?utf-8?B?" . base64_encode($fileatt_name) . "?="; if (ereg("(.*)<(.*)>", $from, $regs)) { // There is a name for the expeditor ! $from = '=?UTF-8?B?'.base64_encode($regs[1]).'?= <'.$regs[2].'>'; } else { // Nothing to do, the from is directly the email ! $from = $from; } $headers = "Content-type: text/plain; charset=UTF-8\r\n"; $headers .= 'From: '.$from.chr(10); if (is_uploaded_file($fileatt)) { // Read the file to be attached ('rb' = read binary) $file = fopen($fileatt,'rb'); $data = fread($file,filesize($fileatt)); fclose($file); // Generate a boundary string $semi_rand = md5(time()); $mime_boundary = "==Multipart_Boundary_x{$semi_rand}x"; // Add the headers for a file attachment $headers .= "\nMIME-Version: 1.0\n" . "Content-Type: multipart/mixed;\n" . " boundary=\"{$mime_boundary}\""; // Add a multipart boundary above the plain message $message = "This is a multi-part message in MIME format.\n\n" . "--{$mime_boundary}\n" . "Content-Type: text/plain; charset=\"UTF-8\"\n" . "Content-Transfer-Encoding: 8bit\n\n" . $message . "\n\n"; // Base64 encode the file data $data = chunk_split(base64_encode($data)); // Add file attachment to the message $message .= "--{$mime_boundary}\n" . "Content-Type: {$fileatt_type};\n" . " name=\"{$fileatt_name}\"\n" . //"Content-Disposition: attachment;\n" . //" filename=\"{$fileatt_name}\"\n" . "Content-Transfer-Encoding: base64\n\n" . $data . "\n\n" . "--{$mime_boundary}--\n"; } else { $headers = "Content-type: text/plain; charset=UTF-8\r\n" . $headers = 'From: '.$from.chr(10); } // Send the message $ok = @mail($to, $subject, $message, $headers); if ($ok) { echo "Email sent!"; } else { echo "Error occured!"; } ?>Can you tell me what I am doing wrong.
- reply
Submitted by Tomas (not verified) on September 19, 2010 - 12:59pm.Post new comment