How to send correct UTF-8 mail in PHP

Tags:  •    •    •  

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]

Great! Working on php 5, 2 years and a half afer this post!

Thanks alot!!

In the same way you can add UTF8 to sender name, receiver name, and subject, thanks!

Submitted by Victor Ocampo (not verified) on January 12, 2010 - 6:25pm.
This seems to work okay when

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.

Submitted by Hotaka (not verified) on August 28, 2009 - 12:35am.
Newbiiieeeeee

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";
}
}
?>

Submitted by TheKing (not verified) on August 25, 2009 - 12:42am.
Thank you

Thank you for the solution. It was very useful. My forum members were complaining about missing characters in the new reply notification emails.

Submitted by Pierrick (not verified) on July 30, 2009 - 11:16pm.
utf8 doesn't show properly in subject

Hi I tried your code but it doesn't show the utf8 code in the subject. Can you help. Thanks.

Submitted by Visitor (not verified) on July 15, 2009 - 12:17pm.
Great

It worked great for sending sweedish characters, thanks a million!

Submitted by Robin (not verified) on July 14, 2009 - 12:48pm.
Dude you must be a deep source of knowledge

How did you come up with this solution? It worked GREAT!

Submitted by eliezer (not verified) on May 7, 2009 - 8:40pm.
After 1.5 years from its

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!

Submitted by blackspot (not verified) on April 28, 2009 - 10:49am.
Thanks!! I've Googled

Thanks!!

I've Googled several hours for solution for my (same) problem and your function helped.

Cheers from Croatia :)

Submitted by Hrvoje (not verified) on April 24, 2009 - 5:18pm.
Exactly a year later, I

Exactly a year later, I found this information extremely useful. Solved my problem with strange characters in the FROM portion. Thanks!

Submitted by boediger (not verified) on February 15, 2009 - 8:46pm.
Using the function instead of 'mail'

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 ;)

Submitted by Visitor (not verified) on February 15, 2009 - 2:11am.
simpler

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))

Submitted by Another Visitor (not verified) on September 18, 2009 - 1:05pm.
Thanks 365 days later...

Exactly a year later, I found this information extremely useful. Solved my problem with strange characters in the FROM portion. Thanks!

Submitted by Robbie (not verified) on December 22, 2008 - 5:13pm.
Trailing "?="

You need a trailing "?=" after the base64-encoded string.
"=?UTF-8?B?".base64_encode($subject)."?="

Best regards.

Submitted by reishi (not verified) on September 1, 2008 - 6:26pm.
Thank you!

I've fixed it. Thank you!

Submitted by Thomas on September 27, 2008 - 2:01am.
you need to fix it in the

you need to fix it in the file as well

Submitted by Visitor (not verified) on January 21, 2009 - 10:42am.
Thanks

Thank you, your comment. I have fixed it also.

Submitted by Thomas on January 22, 2009 - 9:43am.
How would you encode the

Thank, nice piece of code,

But how do you encode the Headers "From:" field if it contains Unicode characters ?

Submitted by GiorgosK (not verified) on December 7, 2007 - 1:14pm.
Here is your solution !

For the from field, like the subject, you have to base64_encode it !

Example :

// $from is expeditor 
 
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;
}
 
// then :
 
$header = 'From: '.$from.chr(10);

And you can do the same for CC header !

Well done ;)
Best regards. Guillaume.

Submitted by Gwouite (not verified) on December 22, 2007 - 9:54pm.

Post new comment

The content of this field is kept private and will not be shown publicly.