【问题标题】:mail with php pear semi-randomly corrupts characters带有php pear的邮件半随机损坏字符
【发布时间】:2022-01-29 22:54:35
【问题描述】:

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

通过 gmail 帐户收到的邮件正文已损坏的示例。有时链接会损坏(它会添加一个空格和/或 x0D / %0D 字符 - 这是回车)。每次,只有一个词被破坏,如下所示。有时被破坏的角色出现在主题中,但很少见。

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。

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

【问题讨论】:

  • 您还需要考虑这些: 1. 在标题中添加MIME-Version: 1.0 以支持不同类型的字符和非文本数据。 2.另一种编码,如charset=iso-8859-1
  • mime 版本标头不能解决问题。我不能使用其他字符集,我需要 utf8
  • 只是为了将来,当你说单独使用pear 时,它没有任何意义,pear 只是 PHP 的扩展框架,你应该总是有一个 pear 扩展,我也想说你想要的很少现在发送邮件的服务器垃圾邮件过滤器很麻烦,你最好使用像mailgun这样的外部服务,因为它们会告诉你一切都是正确的,并且来自半白名单的邮件服务器

标签: php email pear


【解决方案1】:

安装 PEAR 模块 Mail/mime 并设置额外的 mime 标头,即 text_charset 和 html_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>'
        );

【讨论】:

  • 我认为电子邮件现在应该有多个 mime、ASCII、UTF-8 和 UTF-16,所以如果支持它的客户端退回到对电子邮件客户端的最差支持,则可以处理表情符号?
  • 谢谢,成功了。
  • @Barkermn01 我真的不太了解表情符号,但您可以使用多个 mime 来添加,例如,同一电子邮件的 text/html 和 text/plain 版本。在这种情况下,我们只是添加一个 text/html 版本,但我们要添加所需的最重要的字符集信息。
【解决方案2】:

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

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

locale -a

如果没有安装greek,请尝试安装:

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 正在使用上述受 LC_CTYPE 或 LC_COLLATE 影响的函数之一。

请记住文档中的警告:

区域信息是按进程维护的,而不是按线程维护的。如果您在多线程服务器 API 上运行 PHP,您可能会在脚本运行时遇到语言环境设置的突然变化,尽管脚本本身从未调用 setlocale()。这是因为其他脚本同时在同一进程的不同线程中运行,使用 setlocale() 更改了进程范围的语言环境。

参考文献

setlocale php manual

【讨论】:

  • 我正在运行 Windows 服务器。谢谢你的回复,解决方法就是上面那个
猜你喜欢
  • 2011-10-07
  • 2021-08-10
  • 2012-08-11
  • 1970-01-01
  • 2014-01-01
  • 2011-08-25
  • 1970-01-01
  • 2011-10-03
  • 1970-01-01
相关资源
最近更新 更多