If you thought that setting “Content-Type” will suffice to make your email just send away without problems, think again. The specified character encoding in “Content-Type” will only describe the character encoding of the body, not the subject itself. If the subject contains UTF-8 chars your email subject will not look as expected on the recipient. To fix this issue you will need to use the encoded-word syntax (RFC2047#section-2) with either the quoted-printable encoding or the Base64 encoding.
Here is a quick snippet on how I did it:
if (strlen($subject) != strlen(utf8_decode($subject))) //check if subject is utf-8
fwrite($socket, 'Subject: =?UTF-8?B?'.base64_encode(html_entity_decode(utf8_encode($subject), ENT_COMPAT, "UTF-8"))."?="."\r\n".'To: <'.implode('>, <', $recipients).'>'."\r\n".$headers."\r\n\r\n".$message."\r\n");
fwrite($socket, 'Subject: '.$subject."\r\n".'To: <'.implode('>, <', $recipients).'>'."\r\n".$headers."\r\n\r\n".$message."\r\n");
This syntax uses a string of ASCII characters indicating both the original char encoding and the content-transfer-encoding used to map the bytes of the charset into ASCII characters.
The syntax is: “=?charset?encoding?encoded text?=”.
As you can see above I’m trying to see if the “subject” string contains any UTF-8, so it will encode only when necessary. The encoding check I’m doing is fairly simple, and you can also use mb_check_encoding function to do the same thing. I didn’t use it because it requires php_mbstring extension loaded, which is a non-default extension (it is not enabled by default, you must explicitly enable the module in your php.ini).
I’m using fwrite because I’m actually writing/reading directly to sockets (working on a simple SMTP client in PHP). The same rule applies for the standard email php function: the encoded-word syntax is expected for the subject or other header field values if they contain UTF-8 chars (but not for the body).
If you are not happy with the base64 encoding you can use imap_8bit function for the quoted-printable encoding, like this:
Hope this helps. Good luck!