在IMAP服务器上将电子邮件标记为已读

6
我正在尝试从一个IMAP服务器(Gmail)读取邮件。我想检查是否有新邮件(未读),并将其标记为已读。我编写了以下代码,但是...
imap_setflag_full

似乎不起作用。 如果我有一封新邮件,脚本无法设置已读标记,并且它会告诉我始终有一封未读邮件。

  $mbox=imap_open( "{imap.gmail.com:993/ssl/novalidate-cert}" , $this->username, $this->password);
    if ($mbox) 
            {  echo "Connected\n<br><br>"; 
            }  else { exit ("Can't connect: " . imap_last_error() ."\n");  echo "FAIL!\n";  }; 

        if ($hdr = imap_check($mbox)) {
          $msgCount = $hdr->Nmsgs;
          echo "There are ".$msgCount." mail";
        } else {
          echo "Failed to get mail";

        }

        $result = imap_search($mbox, 'UNSEEN');
        echo "<br>Result: ";
        print_r($result);
        if($result==false)
            echo "No email";
        else{
            echo "you have mail"; 
            echo("<br>now I set the Seen flag for this mail");
            rsort($result);
            $status = imap_setflag_full($mbox, "1", "\\Seen \\Flagged", ST_UID);      
        }

        echo"<br><br>";


        $result = imap_search($mbox, 'UNSEEN');
        echo "<br>Result: ";
        print_r($result);
        if($result==false)
            echo "no mail";
        else{
            echo "there are still"; 

        }

非常感谢你。
2个回答

16

我认为问题出在你已经硬编码的“1”上。我将“1”替换为:

foreach ($result as $mail) {
    $status = imap_setflag_full($mbox, $mail, "\\Seen \\Flagged", ST_UID);
}

看起来它是有效的。当使用ST_UID时,这实际上意味着一个ID,而不是序列号。


使用 SE_UID 选项来返回 UID 而不是序列号。 - Matthew
只是为了澄清Matthew的评论:仅当您按内部ID而不是按序列号(默认)搜索消息时,才必须传递ST_UID标志:$result = imap_search($mbox, 'UNSEEN', SE_UID); 这在问题中并没有做到。 - luis.ap.uyen

6
我不知道上面的答案是如何运作的,人们为什么要投票支持那个答案。我已经在那个答案上浪费了一整天的时间。
最终我找到了真正的解决方案。这个方案是可行的。我只需要将未读邮件设置为已读邮件即可。
<?php   
// Connect to gmail
$imapPath = '{imap.gmail.com:993/imap/ssl}INBOX';
//$imapPath = '{imap.gmail.com:993/imap/ssl/novalidate-cert}INBOX';
$username = 'Your-email@gmail.com';
$password = 'Your-Password';
$email_read = 'UNSEEN';

// try to connect
$inbox = imap_open($imapPath,$username,$password) or die('Cannot connect to Gmail: ' . imap_last_error());

$emails = imap_search($inbox,$email_read);
$ids = array();
foreach($emails as $key => $mail) {
    $ids [] = $mail;

    // Do here whatever you want.
}

// Setting flag from un-seen email to seen on emails ID.
imap_setflag_full($inbox,implode(",", $ids), "\\Seen \\Flagged"); //IMPORTANT

// colse the connection
imap_expunge($inbox);
imap_close($inbox);

?>

1
在你的答案中,你将所有未读邮件标记为已读。但是在上面的答案中,我可以根据需要使用不同的条件选择要将哪些电子邮件标记为已读,只需在“foreach”中进行设置即可。 - Khalilullah

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