Search code examples
phpemailpdfutf-8mime

Sending MIME-encoded email attachments with utf-8 filenames


Hello dear people,

I spent the last 3 days searching the web for an answer and I couldn't find any.
I found plenty of "almost" cases but none was exactly what I was looking for.

I am able to get the subject and the body message in Hebrew, but I can't get the attached file name in Hebrew.

Btw, I'm not interested in third party programs like PHPMailer ect.

This is what I get:

W_W(W'W_W_.pdf

This is what I want to get:

שלום.pdf

Here is my code, very simple..

$boundary = uniqid("HTMLEMAIL");
$separator = md5(time());
$eol = PHP_EOL;

// attachment name
$fileName = "שלום.pdf";
var_dump($fileName);

$pdfdoc = $pdf->Output("", "S");
$attachment = chunk_split(base64_encode($pdfdoc));

// main header (multipart mandatory)
$headers = [];
$headers[] = "From: $from";
$headers[] = "MIME-Version: 1.0";
$headers[] = "Content-Type: multipart/mixed; boundary=\"".$separator."\"";
$headers[] = "This is a MIME encoded message.";

// message
$msg = "--".$separator.$eol;
$msg .= "Content-Type: text/html; charset=UTF-8".$eol;
$msg .= "Content-Transfer-Encoding: base64".$eol.$eol;
$msg .= chunk_split(base64_encode($message)).$eol.$eol; 

// attachment
$msg .= "--".$separator.$eol;
$msg .= "Content-Type: application/pdf; name=\"".$fileName."\"".$eol; 
$msg .= "Content-Transfer-Encoding: base64".$eol.$eol;
$msg .= "Content-Disposition: attachment".$eol;
$msg .= $attachment.$eol;
$msg .= "--".$separator."--";

mail($to,'=?UTF-8?B?'.base64_encode($subject).'?=', $msg, implode("\n\r", $headers));

Solution

  • According to RFC2047 you can't have encodings other than ascii in parameters of Content-Type header.

    According to RFC2231 you can try to define extended parameter: Content-Type: application/pdf; name*=utf-8''%D7%A9%D7%9C%D7%95%D7%9D%2E%70%64%66

    I have no idea how well it is supported.

    I can't come up with oneliner for that, but you can try to adapt this one PHP convert string to hex and hex to string

    Update as per comments:
    While specification explicitly forbid that, most mail clients should understand following format 'name="?UTF-8?B?' . base64_encode($filename) . '?='

    I suggest you to use it for sanity sake.