PHP邮件发送:解决变音符号、PDF附件及HTML正文问题
解决PHP发送带FPDF附件邮件的UTF-8变音符号及HTML正文问题
问题核心原因
你的代码存在两个关键问题:
- 邮件头字符未按标准编码:发件人名称、主题里的UTF-8字符(如ü、ä、ö)不能直接传输,必须遵循RFC 2047标准编码,否则会乱码。
- MIME结构不支持多格式正文:原代码仅用
multipart/mixed处理附件,要同时兼容纯文本和HTML正文,需要嵌套multipart/alternative类型的MIME块。
修改后的完整代码
<?php require('fpdf/fpdf.php'); $pdf = new FPDF('P','mm','A4'); $pdf->AddPage(); $pdf->SetFont('Arial','B',16); $pdf->Cell(40,10, "this is a pdf example"); $to = "to@blah.com"; // 编码发件人名称中的UTF-8字符 $fromName = "Bläh mit Ümlauten"; $fromEmail = "blah@blah.de"; $from = mb_encode_mimeheader($fromName, 'UTF-8', 'Q') . " <{$fromEmail}>"; // 编码主题中的UTF-8字符 $subject = mb_encode_mimeheader("Test mit Ümlauten", 'UTF-8', 'Q'); $separator = md5(time()); $eol = PHP_EOL; $filename = "Test.pdf"; $pdfdoc = $pdf->Output("", "S"); $attachment = chunk_split(base64_encode($pdfdoc)); // 主MIME头:multipart/mixed包含正文块和附件 $headers = "From: {$from}{$eol}"; $headers .= "MIME-Version: 1.0{$eol}"; $headers .= "Content-Type: multipart/mixed; boundary=\"{$separator}\"{$eol}{$eol}"; // 正文部分:嵌套multipart/alternative支持纯文本和HTML $body = "--{$separator}{$eol}"; $body .= "Content-Type: multipart/alternative; boundary=\"alt_{$separator}\"{$eol}{$eol}"; // 纯文本备用版本 $body .= "--alt_{$separator}{$eol}"; $body .= "Content-Type: text/plain; charset=utf-8{$eol}"; $body .= "Content-Transfer-Encoding: quoted-printable{$eol}{$eol}"; $body .= "Hallo, dies ist ein Test mit Ümläuten (Plain Text){$eol}{$eol}"; // HTML正文版本 $body .= "--alt_{$separator}{$eol}"; $body .= "Content-Type: text/html; charset=utf-8{$eol}"; $body .= "Content-Transfer-Encoding: quoted-printable{$eol}{$eol}"; $body .= "<html><body>"; $body .= "<h1>Hallo!</h1>"; $body .= "<p>Dies ist ein <strong>HTML-Test</strong> mit Ümläuten.</p>"; $body .= "</body></html>{$eol}{$eol}"; // 结束正文嵌套块 $body .= "--alt_{$separator}--{$eol}{$eol}"; // 附件部分 $body .= "--{$separator}{$eol}"; $body .= "Content-Type: application/pdf; name=\"{$filename}\"{$eol}"; $body .= "Content-Transfer-Encoding: base64{$eol}"; $body .= "Content-Disposition: attachment; filename=\"{$filename}\"{$eol}{$eol}"; $body .= $attachment . $eol; $body .= "--{$separator}--"; // 发送邮件 mail($to, $subject, $body, $headers); // 输出PDF到浏览器 $pdf->Output('I', "Test_mit_Umlauten.pdf"); ?>
关键改动说明
邮件头编码处理:
- 用
mb_encode_mimeheader()对发件人名称、主题进行UTF-8编码(Q编码方式,适合短字符),确保变音符号在邮件头中正常显示。需确保PHP环境启用mbstring扩展(多数环境默认开启)。
- 用
MIME结构优化:
- 外层用
multipart/mixed类型承载正文和附件;正文部分嵌套multipart/alternative,同时提供纯文本和HTML版本,兼容不同邮件客户端。
- 外层用
正文编码设置:
- 为纯文本、HTML正文都指定
charset=utf-8,并使用quoted-printable编码(比base64更适合UTF-8文本,节省传输空间)。
- 为纯文本、HTML正文都指定
附件类型修正:
- 将附件的Content-Type从
application/octet-stream改为更准确的application/pdf,方便客户端识别文件类型;在Content-Disposition中重复指定文件名,提升兼容性。
- 将附件的Content-Type从
内容的提问来源于stack exchange,提问作者djaenz
相关产品推荐
相关产品推荐

