使用 PHPMailer 的 HTML 电子邮件中未很好地显示 UTF-8 重音

UTF-8 Accents not been well displayed in HTML email with PHPMailer

我正在设置一个 PHPMailer PHP 表单,将表单发送到我们的 Office 365 帐户。我对显示的法语口音有疑问,有“Éé àà çç”之类的“Éé àà çç”之类的“ééé à à çç”口音。

PHP 表格以UTF-8编码; PHP代码也用UTF-8编码;

但是收到的电子邮件似乎没有显示正确的字符。

我已经添加了这些设置,但没有任何改变:

在PHP文件中

header('Content-Type: charset=utf-8');

还有

$mail->isHTML(true);     // Set email format to HTML
$mail->CharSet = "UTF-8";

Php发送表单源代码:

<?php
header('Content-Type: charset=utf-8');
ini_set('startup_errors', 1);
ini_set('display_errors', 1);
error_reporting(E_ALL);    

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

require 'php/phpmailer/vendor/phpmailer/phpmailer/src/Exception.php';
require 'php/phpmailer/vendor/phpmailer/phpmailer/src/PHPMailer.php';
require 'php/phpmailer/vendor/phpmailer/phpmailer/src/SMTP.php';

$nom_compagnie = $_POST['nom_compagnie'];
$nom_complet = $_POST['nom_complet'];
$poste = $_POST['poste'];
$email = $_POST['email'];
$telephone = $_POST['telephone'];
$commentaire = $_POST['commentaire'];
$from = $_POST['email'];

function post_captcha($user_response) {
    $fields_string = '';
    $fields = array(
        'secret' => 'PrivateKey',
        'response' => $user_response
    );
    foreach($fields as $key=>$value)
    $fields_string .= $key . '=' . $value . '&';
    $fields_string = rtrim($fields_string, '&');

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, 'https://www.google.com/recaptcha/api/siteverify');
    curl_setopt($ch, CURLOPT_POST, count($fields));
    curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, True);

    $result = curl_exec($ch);
    curl_close($ch);

    return json_decode($result, true);
}
    $res = post_captcha($_POST['g-recaptcha-response']);

if (!$res['success']) {
    // What happens when the reCAPTCHA is not properly set up
    echo 'reCAPTCHA error: Check to make sure your keys match the registered domain and are in the correct locations. You may also want to doublecheck your code for typos or syntax errors.';

} else {
    // If CAPTCHA is successful...
    try {
    $mail = new PHPMailer(true);
    $mail->isSMTP();
    $mail->Host = 'smtp.office365.com';
    $mail->Port = 587;
    $mail->SMTPSecure = 'tls';
    $mail->SMTPAuth = true;
    $mail->Username = 'EmailAccount';
    $mail->Password = 'Password';
    $mail->addReplyTo($from, $nom_complet);
    $mail->SetFrom ("Hidden", "Hidden");
    $mail->addCC ("Hidden", "Hidden");
    $mail->addAddress ('Hidden', 'Hidden);
    //$mail->SMTPDebug = 3;
    //$mail->Debutoutput = fonction($str, $level) {echo "debug level $level; message: $str";}; //

    $mail->isHTML(true);     // Set email format to HTML
    $mail->Subject = "FORMULAIRE CONTACT";
    $mail->Body    = "
    <html>
    <head>
    <meta charset=\"UTF-8\">
    <title>Formulaire de Contact</title>
    ....
    </html>";
    $mail->AltBody = "";
    $mail->CharSet = "UTF-8";

    //$mail->msgHTML(file_get_contents('email_form_contact-fr.html'));
    $mail->send();
    // Paste mail function or whatever else you want to happen here!
    } catch (Exception $e) {
        echo $e->getMessage();
        die(0);
    }
        header('Location: envoi_form_contact-success-fr.html');
}

?>

收到的邮件是这样显示的:

显示邮件中的H3标题

Vous avez reçu un formulaire de contact via le site Web

应该是这样写的

Vous avez reçu un formulaire de contact via le site web

重音符号“é”也显示为“É”。

不知道哪里出了问题

如果我的代码编程良好,有什么线索吗?

谢谢。

你好史蒂芬。 This page 描述了您看到的症状;一个字符变成两个意味着您的数据是 UTF-8,但正在使用 8 位字符集显示。一般来说,PHPMailer 做对了,所以你需要弄清楚哪里出错了。

如果您使用 SMTPDebug = 2,您将能够看到正在发送的消息(使用非常短的消息正文,例如 é,保证 在 UTF-8 中工作)。

确保脚本文件本身的编码也是 UTF-8 - 将表情符号放入其中是确保它是的好方法。

诊断这个问题是你会发现你的 OS 干扰 - 像复制到剪贴板这样的事情可能会改变编码 - 所以处理它的方法是使用十六进制转储功能这使您可以检查实际的字节值。法语是比较容易识别的字符之一,因为几乎所有字符都是常规 single-byte ASCII-compatible 字符,重音字符更容易识别。在 PHP 中,bin2hex() 函数将执行此操作。

你有 2 个错别字:Debutoutput 应该是 Debugoutputfonction 应该是 function - 这是转储十六进制数据的好地方:

$mail->Debugoutput = function($str, $level) {echo $str, "\n", bin2hex($str), "\n";};

这是一个例子:

echo 'abc ', bin2hex('abc');

这将产生 abc 616263;每个输入字符都会产生 2 个十六进制数字(1 个字节)的输出。如果您的输入是 abé 并且您的字符集是 ISO-8859-1,它将显示为 abé 6162e9,因为该字符集中的 é 是 e9(十六进制)。 UTF-8 中的 same 字符串会输出为 abé 6162c3a9,因为 UTF8 中的 é 是 c3a9 - two 字节,不止一个。像这样检查字符可以让您绝对确定数据在哪个字符集中 - 仅仅看它是不够的!

因此,虽然我无法准确判断您的问题出在哪里,但希望您对如何诊断它有一些更好的想法。

替换

$mail -> charSet = "UTF-8"; 

$mail->CharSet = 'UTF-8';