PHP imap_search:Microsoft Exchange邮件服务器上的UTF-8 /非ASCII字符

时间:2019-05-03 21:01:41

标签: php character-encoding office365 exchange-server imap

我想使用IMAP和PHP从outlook.office365.com获取电子邮件。

由于大多数电子邮件包含äöü之类的非ASCII字符,因此我在UTF-8函数中使用了imap_search()

imap_search($mbox_connection, 'ALL', SE_UID, "UTF-8")

使用UTF-8和搜索条件ALL,我收到了所有预期的电子邮件。现在,我想将其限制为例如仅看不见(未读)的电子邮件:

imap_search($mbox_connection, 'UNSEEN', SE_UID, "UTF-8")

但是,不幸的是,这导致了问题,即使找不到电子邮件,也再也找不到电子邮件了-而且还会引发此PHP通知:

PHP Notice:  Unknown: [BADCHARSET (US-ASCII)] The specified charset is not supported. (errflg=2) in Unknown on line 0

基于此通知,我将字符集从UTF-8更改为US-ASCII

imap_search($mbox_connection, 'UNSEEN', SE_UID, "US-ASCII")

现在,它将返回所有预期的未见(未读)电子邮件。

现在的问题是,我无法搜索带有UTF-8字符的电子邮件。例如,我有一封包含以下信息的电子邮件:

  • 来自:ÄpfelNürnberg
  • 主题:Apfel与Äpfel
  • 身体:
Einzahl gegen Mehrzahl.

Ein Apfel, mehrere Äpfel.

当我尝试搜索所有主题为“ apfel”的电子邮件时,它会按预期工作-我可以找到该电子邮件:

imap_search($mbox_connection, 'FROM "apfel"', SE_UID, "US-ASCII")
Trying to connect to '{outlook.office365.com:993/imap/ssl}INBOX'...
Found 1 email(s)...
+------ P A R S I N G ------+
From: =?iso-8859-1?Q?=C4pfel=20N=FCrnberg?= <=?iso-8859-1?Q?=C4pfel=20N=FCrnberg?= <aepfel@nuernberg.de>>
Subject: =?iso-8859-1?Q?Apfel_vs._=C4pfel?=

但是当我改为搜索带有UTF-8字符的单词(在这种情况下为äpfel)时,找不到电子邮件:

imap_search($mbox_connection, 'FROM "äpfel"', SE_UID, "US-ASCII")

由于这个事实,我将字符集从US-ASCII改回了UTF-8,但这仅在错误消息[BADCHARSET (US-ASCII)]处结束。

我的代码很简单:

$mailbox = "{outlook.office365.com:993/imap/ssl}INBOX";
$mailbox_username = "someone@outlook.com";
$mailbox_password = "*******";

echo "Trying to connect to '$mailbox'...\n";

$mbox_connection = imap_open($mailbox, $mailbox_username, $mailbox_password);

$mailsIds = imap_search($mbox_connection, 'SUBJECT "äpfel"', SE_UID, "UTF-8");

if(!$mailsIds) {
    echo "No emails found!\n";
    imap_close($mbox_connection);
    die();
}

echo "Found " . count($mailsIds) . " email(s)...\n";

foreach($mailsIds as $mailId) {
    echo "+------ P A R S I N G ------+\n";

    $headersRaw = imap_fetchheader($mbox_connection, $mailId, FT_UID);
    $header = imap_rfc822_parse_headers($headersRaw);

    echo "From: " . $header->from[0]->personal . " <" . $header->fromaddress . ">\n";
    echo "Subject: " . $header->subject . "\n";
}

我已经尝试过此解决方案,但这也不会返回匹配的电子邮件:

$str = "äpfel";
$str = preg_replace('/\=\?ISO\-8859\-1\?Q\?/i', '', mb_encode_mimeheader($str, "ISO-8859-1", "Q"));
$mailsIds = imap_search($mbox_connection, 'SUBJECT "'.$str.'"', SE_UID, 'US-ASCII');

任何想法,当IMAP服务器不支持From时,如何在电子邮件字段SubjectBodyUTF-8中搜索非ASCII字符还不能在服务器端配置上更改此设置?

这似乎是所有Microsoft Exchange服务器的问题。据我所知,只有那些服务器存在此问题。

1 个答案:

答案 0 :(得分:2)

您可能不能。

Exchange似乎没有实现IMAP的字符集感知搜索,并且这不是RFC3501的要求(必须仅支持US-ASCII)。通常支持UTF-8,但对于Exchange似乎并非如此。

您将不得不切换协议(EAS,EWS,REST服务等)或提取信息,自己解码并搜索。如果您将其缓存,则从长远来看还算不错。由于它是标题,因此可以一次获取所有内容。如果您需要搜索尸体,情况会更加困难。