PHP带有重音符号的邮件

3
我在发送包含重音符号的邮件主题时遇到了问题。我已经在各处搜寻过,但所有的解决方案都不起作用。
我有一个字符串,邮件主题,可能是使用 iso-8859-1 编码,在命令行脚本中发送。
$res = shell_exec(sprintf("php mail.php %s %s %s %s",
   escapeshellarg($email->sender),
   escapeshellarg($receiver->email),
   escapeshellarg($email->subject),
   escapeshellarg($email->message)
));

邮件的标题是:
$headers  = "MIME-Version: 1.0" . $endl;
$headers .= 'Content-type: text/html; charset="iso-8859-1"' . $endl;
$headers .= 'Content-Transfer-Encoding: 8bit';

结果是,我收到了一个主题为“????” 的电子邮件。

注意:在Windows本地测试通过。

示例代码

testmail.php

<?php
$sender = "me@gmail.com";
$receiver = "you@mgmail.com";
$subject = "Accentued éàèçô letters";
$msg = "Accentued éàèçô letters";

shell_exec(sprintf('LANG="fr_FR.iso88591"; php mail.php %s %s %s %s > /dev/null 2>/dev/null &',
                        escapeshellarg($sender),
                        escapeshellarg($receiver),
                        escapeshellarg($subject),
                        escapeshellarg($msg)
                    ));
?>

mail.php

<?php

if ($argc!=5) exit;

$sender = $argv[1];
$receiver = $argv[2];
$subject = $argv[3];
$msg = $argv[4];

$endl = "\r\n";

//HTML header
$headers = "From: $sender" . $endl;
$headers .= "MIME-Version: 1.0" . $endl;
$headers .= "Content-type: text/html; charset=iso-8859-1" . $endl;
$headers .= 'Content-Transfer-Encoding: 8bit';


 $msg = "
         <html>
      <head>
       <title></title>
      </head>
      <body>
                $msg
      </body>
     </html>
     ";

$receiver = explode(',', $receiver);

foreach ($receiver as $rec)
{
    mail($rec, $subject, $msg, $headers);
    sleep(5);
}
?>

执行:php testmail.php 在Linux上测试。

解决方案 解决此问题的正确方法是使用base64_encode。

'=?UTF-8?B?' . base64_encode($subject) . '?=';

1
请参考已接受答案底部的链接:https://dev59.com/gkrSa4cB1Zd3GeqPU0S0 - pbond
1
可能是编码问题?适当的标点和重音取决于所使用的编码!“可能”并不好!你需要确切地知道所使用的编码! - Zuul
@peterbond:尝试过了。首先,我不应该使用文本/纯文本内容类型。其次,我尝试了base64编码,但没有成功。问题在于命令行编码,在Windows中,它是Windows-1252。在其他系统中可能会有所不同。 - Thanh Trung
@Zuul:它来自一个使用iso-8859-1编码的HTML表单,因此它必须是iso-8859-1编码。 - Thanh Trung
过去我曾遇到电子邮件主题的问题,因为表单/PHP文件/变量等不是同一字符集!但实际上这并不会弄乱结果,事实上应该都在同一个字符集中! - Zuul
显示剩余3条评论
2个回答

1

好的,在对您的问题进行多次测试后,这里是基于您当前代码的可行解决方案:

MAIL.PHP (文件保存为UTF8编码)

<?php

if ($argc!=5) exit;

$sender = $argv[1];
$receiver = $argv[2];
$subject = $argv[3];
$msg = $argv[4];

$endl = "\r\n";

// HTML header
$headers = "From: $sender" . $endl;
$headers.= 'MIME-Version: 1.0' . "\r\n";
$headers.= 'Content-type: text/html; charset=UTF-8' . "\r\n";
$headers.= 'Content-Transfer-Encoding: 8bit';

// Message
$msg = "
<html>
  <head>
    <title></title>
  </head>
  <body>
    $msg
  </body>
</html>";

$receiver = explode(',', $receiver);

foreach ($receiver as $rec) {
    mail($rec, $subject, $msg, $headers);
    sleep(5);
}

?>

TESTMAIL.PHP (文件保存为UTF8编码)

<?php

$sender = "inbox@domain.com";
$receiver = "outbox@domain.com";
$subject = "Accentued éàèçô letters";
$msg = "Accentued éàèçô letters";

setlocale(LC_CTYPE, "en_US.UTF-8");
shell_exec(sprintf('"LANG=en_US.UTF-8"; php mail.php %s %s %s %s > /dev/null 2>/dev/null &',
                        escapeshellarg($sender),
                        escapeshellarg($receiver),
                        escapeshellarg($subject),
                        escapeshellarg($msg)
                    ));
?>

我已经测试过了,所有的邮件都正确接收了。


我已经尝试过了,但仍然没有成功,你能否尝试编写一个脚本来模拟这种情况吗?实际上,我使用的是LANG="fr_FR.iso88591"。尝试了utf8、"、去掉分号等方法,但仍然无法正常工作。我使用法语键盘输入带重音符号的字母。 - Thanh Trung
请更新您的答案,附上完整的PHP代码,以便我可以在这里测试它! - Zuul
@Thanh Trung,我刚刚更新了我的答案,并提供了一个经过测试的可行更新来修复你的代码! - Zuul
问题可能是由于我的邮件应用程序引起的。在 Gmail 上进行了测试,并且可以正常工作,无需设置区域设置和语言。Escapeshellarg 还会导致问题:它会删除带重音的字母。 - Thanh Trung
你需要更深入地查看你的应用程序!我回答中的代码可以正常工作并发送带重音符号的字母,使用 UTF-8。考虑使用它来解决当前方法中的编码问题! - Zuul
我尝试了你的方法,但我认为真正的问题在于我使用的邮件应用程序不如Gmail好。此外,执行脚本的服务器的配置是否允许您更改语言环境也是一个问题。 - Thanh Trung

0

如果电子邮件的标题不是7位US-ASCII,则需要对其进行RFC2047编码。您已经拥有的MIME声明仅涵盖正文,而不涉及标题。

通常情况下,除非您想了解电子邮件的工作原理,否则舒适且正确的解决方案是找到一个可以为您正确处理此类问题的库。我不熟悉PHP,但这是StackOverflow上的常见问题,答案通常涉及PEAR。


请参见https://dev59.com/MVzUa4cB1Zd3GeqP69Wo。 - tripleee

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接