imap_thread() 返回线程,但仅限于你在 imap_open() 中定义的当前打开的邮箱。这对于例如获取完整线程(来自“已发送邮件”和“收件箱”[我花了一天才弄明白这一点])来说并没有用。
如果你比较 Outlook 和 gmail.com 上的线程,你会发现 Outlook 根据主题标题来确定线程,而不是实际的父子关系。
然而,Gmail 似乎正确地获取了线程,但是不包括你使用他们的 Web 界面在 {imap.google.com:993/imap/ssl}Sent Messages 中发送的邮件。这意味着使用 php imap 的线程对于 Gmail 来说并不完美。
如果你使用 Outlook(或任何邮件客户端)发送邮件,gmail.com 会将其放入他们的“已发送邮件”中。
总而言之,PHP imap 的线程并不完美。但我更责备 imap 规范(尊敬的 IMAP 开发者们,请添加更好的 uid 和父 ID。谢谢 Chris)而不是 PHP。
所以我创建了下面的 Outlook 线程方法(比较主题)
<?php
$imap = imap_open('{imap.gmail.com:993/imap/ssl}INBOX', 'youremail@gmail.com', 'yourpassword');
$subject = 'Item b';
$threads = array();
$subject = trim(preg_replace("/Re\:|re\:|RE\:|Fwd\:|fwd\:|FWD\:/i", '', $subject));
$results = imap_search($imap, 'SUBJECT "'.$subject.'"', SE_UID);
if(is_array($results)) {
$emails = imap_fetch_overview($imap, implode(',', $results), FT_UID);
foreach ($emails as $email) {
$threads[strtotime($email->date)] = $email;
}
}
imap_reopen($imap, '{imap.gmail.com:993/imap/ssl}Sent Messages');
$results = imap_search($imap, 'SUBJECT "'.$subject.'"', SE_UID);
if(is_array($results)) {
$emails = imap_fetch_overview($imap, implode(',', $results), FT_UID);
foreach ($emails as $email) {
$threads[strtotime($email->date)] = $email;
}
}
ksort($threads);
echo '<pre>'.print_r($threads, true).'</pre>';
exit;
?>
因此,如果您要将imap_thread()用于一些有用的目的,这可能是我能想到的最优方法。
<?php
$imap = imap_open('{imap.gmail.com:993/imap/ssl}INBOX', 'youremail@gmail.com', 'password');
$threads = $rootValues = array();
$thread = imap_thread($imap);
$root = 0;
foreach ($thread as $i => $messageId) {
list($sequence, $type) = explode('.', $i);
if($type != 'num' || $messageId == 0
|| ($root == 0 && $thread[$sequence.'.next'] == 0)
|| isset($rootValues[$messageId])) {
continue;
}
if($root == 0) {
$root = $messageId;
}
$rootValues[$messageId] = $root;
if($thread[$sequence.'.next'] == 0) {
$root = 0;
}
}
$emails = imap_fetch_overview($imap, implode(',', array_keys($rootValues)));
foreach ($emails as $email) {
$root = $rootValues[$email->msgno];
$threads[$root][] = $email;
}
echo '<pre>'.print_r($threads, true).'</pre>';
imap_close($imap);
exit;
?>