【问题标题】:Is there an error in PHP's imap_fetch_overview()-function when reading headers with brackets?读取带括号的标头时,PHP 的 imap_fetch_overview() 函数是否有错误?
【发布时间】:2012-08-12 23:09:34
【问题描述】:

我正在使用以下代码在 PHP 中发送电子邮件:

<?php
error_reporting(E_ALL);

# write mail
###############################################################################
$recipient  = "mail@server.tld";
$subject    = mb_encode_mimeheader("Subject äöü ");
$text       = "Hallo";
$header     = "From:".mb_encode_mimeheader("Name with [], ÄÖÜ and spaces")." <webmaster@example.com>"
                . "\r\n" . "Reply-To: webmaster@example.com"
                . "\r\n" . "X-Mailer: PHP/" . phpversion();

// send e-mail
mail($recipient, $subject, $text, $header);
?>

之后我尝试在以下代码中使用imap_fetch_overview() 阅读电子邮件:

<?php
# receive mails
###############################################################################
$mailbox        = imap_open("{imap.server.tld/norsh}", "mail@server.tld", "********");

$MC = imap_check($mailbox);
$result = imap_fetch_overview($mailbox,"1:{$MC->Nmsgs}",0);

echo "<table>";
foreach ($result as $overview) {
    echo "<tr>"
        ."<td>".$overview->msgno."</td>"
        ."<td>".$overview->uid."</td>"
        ."<td>".$overview->date."</td>"
        ."<td>".$overview->udate."</td>"
        ."<td>".$overview->from."</td>"
        ."<td>".$overview->to."</td>"
        ."<td>".$overview->size."</td>"
        ."<td>".$overview->subject."</td>"
        ."</tr>";
}
echo "</table>";
?>

我收到以下错误:

Notice: Undefined property: stdClass::$from in /mail_test.php on line 34

$overview-&gt;from 没有任何价值。

当“From:”部分不包含括号时,没有问题。 我还必须对括号进行编码吗? 如何?我认为mb_encode_mimeheader() 正在做这项工作。

编辑:

var_dump($overview) 的结果是:

object(stdClass)#18 (14) {
  ["subject"]=>
  string(40) "Subject =?UTF-8?B?w4PCpMODwrzDg8K2IA==?="
  ["to"]=>
  string(16) "mail@server.tld"
  ["date"]=>
  string(31) "Thu, 16 Aug 2012 16:58:23 +0200"
  ["message_id"]=>
  string(58) "<**************************************>"
  ["size"]=>
  int(1585)
  ["uid"]=>
  int(18)
  ["msgno"]=>
  int(17)
  ["recent"]=>
  int(1)
  ["flagged"]=>
  int(0)
  ["answered"]=>
  int(0)
  ["deleted"]=>
  int(0)
  ["seen"]=>
  int(0)
  ["draft"]=>
  int(0)
  ["udate"]=>
  int(1345129104)
}

【问题讨论】:

  • 你能粘贴var_dump($overview)的结果吗?
  • 这只是很奇怪且绝对出乎意料的行为,您的代码在这里似乎并没有错。我唯一可以建议的是,当您设置From: 标头时,它可能不喜欢: 和标头数据之间缺少的空格。尝试将 $header = "From:".mb_encode_mimeheader(... 更改为 $header = "From: ".mb_encode_mimeheader(... 看看是否会有所不同 - 尽管我有点怀疑它会。
  • 似乎imap_fetch_overview() 和一些邮件程序无法处理括号 [] :正如我所说:当我删除括号时,一切正常。我查看了 RFC2822 faqs.org/rfcs/rfc2822.html (3.2.1. Primitive Tokens),并认为我还必须转义/编码括号。我检查了几个邮件头,发现括号通常用于 IP 地址。但我不知道邮件头中 [] 的确切含义。
  • From: "Name[with brackets]" &lt;email@tld&gt; 不起作用?
  • 使用引号时,PHP 不显示警告。但是我仍然不知道这是否是 PHP 问题,或者由于 RFC 在这种情况下需要设置引号。我开始了一些其他线程从不同方面解决问题,我总是得到答案“不要在你的标题中使用引号,这是没有必要的”。这让我想到,这可能是 PHP 的问题,而不是不正确的标题。最好有一个函数,对标题中具有特殊含义的所有字符进行编码/转义,以便在标题的“替代名称”部分中使用它们时不会出现问题。

标签: php email email-headers


【解决方案1】:

不久前我也遇到了同样的括号问题。没有人能告诉我,mail-header-adress-fields 中的括号是什么意思,为什么 PHP 不能管理它们。我的解决方案是在使用 imap_fetchheader() 后简单地从地址字段中删除括号。

【讨论】:

    【解决方案2】:

    未添加 FROM 字段是因为您在 php.ini 中没有活动的 from="john@doe.com"(检查 ;)和您的 mb_encode_mimeheader 它没有按照您的需要进行转换,并且无法正确发送电子邮件。

    对于带有 UTF-8 字符和名称的电子邮件,您应该使用 UTF-8base64_encode 进行编码。

    这是发送该电子邮件的正确方法:

    $recipient  = "mail@server.tld";
    $subject    = "=?UTF-8?B?".base64_encode('Subject äöü')."?=";
    $text       = "Hallo";
    $from_user  = "=?UTF-8?B?".base64_encode('Name with [], ÄÖÜ and spaces')."?= <webmaster@example.com>";
    $header     = "From: ".$from_user." "
                    . "\r\n" . "Reply-To: ".$from_user." "
                    . "\r\n" . "MIME-Version: 1.0"
                    . "\r\n" . "Content-Transfer-Encoding: 8bit"
                    . "\r\n" . "Content-type: text/plain; charset=UTF-8"
                    . "\r\n" . "X-Mailer: PHP/" . phpversion();
    
    // send e-mail
    mail($recipient, $subject, $text, $header);
    

    您应该会收到带有正确名称、电子邮件和主题的电子邮件。您仍然需要使用iconv_mime_decode($overview-&gt;from,0, "UTF-8") 解码这些文件

    【讨论】:

      【解决方案3】:

      问题来了

      echo mb_encode_mimeheader("Name with [], ÄÖÜ and spaces");
      

      返回

      Name with [], =?UTF-8?B?w4PChMODwpbDg8KcIGFuZCBzcGFjZXM=?=
      

      这不是,你想要什么。

      我找到了this function on php.net,可能对你有帮助:

      function EncodeMime($Text, $Delimiter) { 
          $Text = utf8_decode($Text); 
          $Len  = strlen($Text); 
          $Out  = ""; 
          for ($i=0; $i<$Len; $i++) 
          { 
              $Chr = substr($Text, $i, 1); 
              $Asc = ord($Chr); 
      
              if ($Asc > 0x255) // Unicode not allowed 
              { 
                  $Out .= "?"; 
              } 
              else if ($Chr == " " || $Chr == $Delimiter || $Asc > 127) 
              { 
                  $Out .= $Delimiter . strtoupper(bin2hex($Chr)); 
              } 
              else $Out .= $Chr; 
          } 
          return $Out; 
      } 
      echo EncodeMime("Name with [], ÄÖÜ and spaces", '%');
      

      返回

      Name%20with%20[],%20%C4%D6%DC%20and%20spaces
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-03-01
        • 1970-01-01
        • 1970-01-01
        • 2020-06-21
        • 2019-11-11
        • 2016-05-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多