带有 php pear 的邮件半随机损坏字符

mail with php pear semi-randomly corrupts characters

我正在通过 pear 发送电子邮件,但最终结果有时会出现损坏的字符。尽管电子邮件大致相同(几个词发生变化,收件人的电子邮件地址),但损坏的字符并不总是在 html 正文的同一位置。你能看到一些奇怪的东西吗?那里的人物。通过 php PEAR 发送电子邮件如下:

在正文损坏的 gmail 帐户上收到的电子邮件示例。有时链接会损坏(它会添加一个 space and/or x0D / %0D 字符 - 即回车符 return)。每次,只有一个词会像下面这样损坏。有时主题中会出现损坏的字符,但很少见。

Received: from localhost (some.domain.com [1.2.3.4]) (Authenticated sender: xxx@mydomain.com) by blabla.domain.com (ESMTP) with ESMTPSA for <recipient@gmail.com>; Tue, 25 Jan 2022 01:06:05 +0200 (EET)
From: xxx@mydomain.com
To: recipient@gmail.com
Date: Tue, 25 Jan 2022 01:06:04 +0200
Content-Type: text/html; charset=UTF-8
X-Mailer: PHP/7.x.x
Reply-To: xxx@mydomain.com
Subject: my subject

<html><head><meta http-equiv="Content-Language" content="el"/><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/></head><body>...Content in greek here... όμορφος, πα�
 �άτε εκεί ... content here</body></html>

而不是单词“πατìτε”

php_script_sending_mail.php

                $UserMesssage = "some greek content here which gets corrupted at usually one word";
                $MAILto      = $varEmail;
                $MAILmessage = "<html><head><meta http-equiv=\"Content-Language\" content=\"el\"/><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/></head><body>";
                $MAILmessage .= $UserMesssage;
                $MAILmessage .= "</body></html>";

                mail_new($MAILto, $MAILsubject, $MAILmessage);

fn_mail.php

    function mail_new($to, $subject, $message) {
        require_once "Mail.php";
        
        $from = "xxx@mydomain.com";

        $host = "mailgate.isp.com";
        $username = "xxx@mydomain.com";
        $password = "pass";

        $headers = array ('From' => $from, 'To' => $to, 'Date' => date('r', time()), 'Content-Type' => 'text/html; charset=UTF-8', 'X-Mailer' => 'PHP/'.phpversion(), 'Reply-To' => 'xxx@mydomain.com', 'Subject' => '=?UTF-8?B?'.base64_encode($subject).'?=');
        $smtp = @Mail::factory('smtp', array ('host' => $host, 'auth' => true, 'username' => $username, 'password' => $password));
     
        $mail = @$smtp->send($to, $headers, $message);
     
    }

两个文件都保存为无 BOM 的 UTF-8。

我做错了什么吗?我该如何解决这个问题? 提前谢谢你。

安装 PEAR 模块 Mail/mime 并设置额外的 mime headers,即 text_charsethtml_charset.

<?php

function mail_new($to, $subject, $message) {
    require_once "Mail.php";
    require_once 'Mail/mime.php';

    $from = "xxx@mydomain.com";

    $host = "mailgate.isp.com";
    $username = "xxx@mydomain.com";
    $password = "pass";

    $headers = array ('From' => $from, 'To' => $to, 'Date' => date('r', time()), 'Content-Type' => 'text/html; charset=UTF-8', 'X-Mailer' => 'PHP/'.phpversion(), 'Reply-To' => 'xxx@mydomain.com', 'Subject' => '=?UTF-8?B?'.base64_encode($subject).'?=');

    $mime = new Mail_mime();
    $mime->setHTMLBody($message);
    $mimeparams = array();
    $mimeparams['text_charset'] = "UTF-8";
    $mimeparams['html_charset'] = "UTF-8";
    $message = $mime->get($mimeparams);
    $headers = $mime->headers($headers);

    $smtp = @Mail::factory('smtp', array ('host' => $host, 'auth' => true, 'username' => $username, 'password' => $password));

    $mail = @$smtp->send($to, $headers, $message);

}

mail_new('xxx@mydomain.com',
         'Test Message',
        '<html><body>Α α, Β β, Γ γ, Δ δ, Ε ε, Ζ ζ, Η η, Θ θ, Ι ι, Κ κ, Λ λ, Μ μ, Ν ν, Ξ ξ, Ο ο, Π π, Ρ ρ, Σ σ/ς, Τ τ, Υ υ, Φ φ, Χ χ, Ψ ψ, Ω ω.</body></html>'
        );

我假设您使用的是 unix 服务器(或本地主机)并且可以完全访问它。我不确定以下是否能解决您的问题,请尝试一下。

第 1 步)找出您的 find ubuntu locale list 中安装了哪些语言环境,在终端中:

locale -a

如果没有安装希腊语,请尝试安装它:

sudo locale-gen el_GR
sudo locale-gen el_GR.utf8

要更新语言环境信息:

sudo update-locale 

第 2 步)尝试在脚本顶部设置语言环境:

setlocale(LC_CTYPE, "el_GR.utf8");
setlocale(LC_COLLATE, "el_GR.utf8");

您可以通过以下方式获取使用的语言环境列表:

echo setlocale(LC_ALL, 0);

根据文档:

  • LC_COLLATE 进行字符串比较,见strcoll()
  • LC_CTYPE用于字符分类和转换,例如strtoupper()

可能 Mail.php 正在使用受 [=56= 影响的上述功能之一]LC_COLLATE.

请记住文档中的警告:

The locale information is maintained per process, not per thread. If you are running PHP on a multithreaded server API , you may experience sudden changes in locale settings while a script is running, though the script itself never called setlocale(). This happens due to other scripts running in different threads of the same process at the same time, changing the process-wide locale using setlocale().

参考资料

setlocale php manual