PHP mail special characters in subject field

Viewed 25688

I would like to insert special characters in the subject of HTML e-mails sent with the PHP mail() function.

I want my subject to look like this:

★ Your new account

I have tried with an HTML entity like ★ (★) or by pasting the symbol directly in my code but that doesn't work either, except on a few e-mail clients.

$to = 'me@example.com';
$subject = '★ Your new account or ★ Your new account';
$message = 'HTML message...';

$headers = 'MIME-Version: 1.0' . "\r\n";
$headers .= 'Content-type: text/html; charset=utf-8' . "\r\n";
$headers .= 'From: Me <me@example.com>' . "\r\n";

mail($to, $subject, $message, $headers);

Any advice on how to get this to work properly? Thank you.

4 Answers

While the accepted answer works fine, it makes it impossible to read the subject when looking at the raw headers. Here's an alternative that keeps the line readable and also shorter if it consists of mostly ascii characters.

$subject = '=?UTF-8?q?' . quoted_printable_encode($subject) . '?=';

Here's the encoded subject line of the accepted answer:

=?UTF-8?B?4piFIFlvdXIgbmV3IGFjY291bnQ=?=

Here's the encoded subject line of my answer:

=?UTF-8?q?=E2=98=85 Your new account?=

Edit:

It turns out quoted_printable_encode() splits long strings into multiple lines of max 75 characters, as required per RFC 2045. This resulted is a string that cannot be used with mail()'s $subject parameter. Here's an updated version to fix this. It will also avoid encoding pure-ascii subjects.

/**
 * Make sure the subject is ASCII-clean
 *
 * @param string $subject Subject to encode
 *
 * @return string Encoded subject
 */
function getEncodedSubject(string $subject): string {
    if (!preg_match('/[^\x20-\x7e]/', $subject)) {
        // ascii-only subject, return as-is
        return $subject;
    }
    // Subject is non-ascii, needs encoding
    $encoded = quoted_printable_encode($subject);
    $prefix = '=?UTF-8?q?';
    $suffix = '?=';
    return $prefix . str_replace("=\r\n", $suffix . "\r\n  " . $prefix, $encoded) . $suffix;
}

Explanation:

$subj = "Lorem ipsuöm dolor sit amet, consectetur adipiscing elit. Praesent mattis molestie purus, non semper lectus dictum eget.";

After quoted_printable_encode

Lorem ipsu=C3=B6m dolor sit amet, consectetur adipiscing elit. Praesent mat=
tis molestie purus, non semper lectus dictum eget.

After str_replace

=?UTF-8?q?Lorem ipsu=C3=B6m dolor sit amet, consectetur adipiscing elit. Praesent mat?=
  =?UTF-8?q?tis molestie purus, non semper lectus dictum eget.?=

If you change HEADERS Charset to charset=iso-8859-1, then you can simply paste the "emoji' in the subject.

This works for me - emails have sad face in subject. Also worked for "From":

$subject = "Email subject";
$headers = "From: Me <me@example.com> \r\n";
$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
$sub =   " ". $subject;
mail($to, $sub, $msg, $headers);

NOTE: I edited this in cPanel File Editor. I don't know if this will work if edited in local code editor, and uploaded via FTP

Related