如何使用PHP移动大量邮件?

如何使用PHP移动大量邮件?,php,email,imap,Php,Email,Imap,我正在尝试编写一个PHP程序,它使用IMAP PHP扩展来运行一个非常大的收件箱(超过70000封电子邮件),并将指定日期范围内的所有电子邮件移动到一个文件夹中。我一直在尝试获取所需范围内的邮件时遇到问题 首先,我尝试使用imap_search()中的“自”和“前”条件将所有所需的ID号放入一个数组中,然后创建一个列有这些ID号的字符串,以输入imap_mail_move()。但我一直遇到的问题是,imap_search()实际上从未返回指定范围内的所有电子邮件。例如,我运行了以下代码:

我正在尝试编写一个PHP程序,它使用IMAP PHP扩展来运行一个非常大的收件箱(超过70000封电子邮件),并将指定日期范围内的所有电子邮件移动到一个文件夹中。我一直在尝试获取所需范围内的邮件时遇到问题

首先,我尝试使用imap_search()中的“自”和“前”条件将所有所需的ID号放入一个数组中,然后创建一个列有这些ID号的字符串,以输入imap_mail_move()。但我一直遇到的问题是,imap_search()实际上从未返回指定范围内的所有电子邮件。例如,我运行了以下代码:

    echo "Beginning search. \n";
    $mail = imap_search($this->mbox, 
                   'SINCE "$startDate" BEFORE "$endDate"');
    echo "Search complete. \n";
    if (!$mail){echo "The inbox is empty. \n"; die();}

    $count = 0;
    foreach($mail as $i)
    {
        $count = $count + 1;
    }
    echo "Found $count emails. \n";
    // Get all mail in the INBOX
    $mail = imap_search($this->mbox, "ALL");
    if (!$mail){echo "The inbox is empty. \n"; die();}

    // Create a string list of all message IDs 
    //that fall in the specified range
    $processed = 0;
    $IDsequence = '';
    foreach($mail as $messageID)
    {
        $date = imap_headerinfo($this->mbox, $messageID)->date;
        try {$dateObject = new DateTime($date);}
        catch (Exception $e) {echo $e->getMessage(); echo "\n";}
        $dateObject->setTimezone($TimeZone); 
        if ($dateObject <= $IntervalEndDate && $dateObject >=
                          $IntervalStartDate)
        {
            $IDsequence = $IDsequence . "," . strval($messageID);
        }
        $processed = $processed + 1;
        if ($processed % 100 == 0)
        { echo "Processed $processed emails. \n"; }

    }
    // If we got at least one message, cut off the first comma.
    if (strlen($IDsequence) > 1){
        $IDsequence = substr($IDsequence, 1, strlen($IDsequence)-1);
    }
    else
    {
        echo "No e-mail to move. \n";
        die();
    }
    echo "Beginning copy. \n";
    imap_mail_copy($this->mbox, $IDsequence, $TargetFolder);
    echo "Copy complete. \n";
    //imap_expunge($this->mbox);
    imap_close($this->mbox);
虽然指定了一个我知道可以保存600封电子邮件的日期范围,但imap_search()只列出了其中的259封。当我将范围扩大到包含75000封电子邮件的整个收件箱时,imap_search()只返回了25112封邮件

当这不起作用时,我尝试了一种不同的、较慢的方式来获取所需日期范围内的所有电子邮件。我使用imap_search()收集收件箱中的所有电子邮件,然后迭代每封电子邮件,将电子邮件标题中包含的日期与定义间隔的日期进行比较,如果在范围内,则将ID添加到字符串中。我运行了以下代码:

    echo "Beginning search. \n";
    $mail = imap_search($this->mbox, 
                   'SINCE "$startDate" BEFORE "$endDate"');
    echo "Search complete. \n";
    if (!$mail){echo "The inbox is empty. \n"; die();}

    $count = 0;
    foreach($mail as $i)
    {
        $count = $count + 1;
    }
    echo "Found $count emails. \n";
    // Get all mail in the INBOX
    $mail = imap_search($this->mbox, "ALL");
    if (!$mail){echo "The inbox is empty. \n"; die();}

    // Create a string list of all message IDs 
    //that fall in the specified range
    $processed = 0;
    $IDsequence = '';
    foreach($mail as $messageID)
    {
        $date = imap_headerinfo($this->mbox, $messageID)->date;
        try {$dateObject = new DateTime($date);}
        catch (Exception $e) {echo $e->getMessage(); echo "\n";}
        $dateObject->setTimezone($TimeZone); 
        if ($dateObject <= $IntervalEndDate && $dateObject >=
                          $IntervalStartDate)
        {
            $IDsequence = $IDsequence . "," . strval($messageID);
        }
        $processed = $processed + 1;
        if ($processed % 100 == 0)
        { echo "Processed $processed emails. \n"; }

    }
    // If we got at least one message, cut off the first comma.
    if (strlen($IDsequence) > 1){
        $IDsequence = substr($IDsequence, 1, strlen($IDsequence)-1);
    }
    else
    {
        echo "No e-mail to move. \n";
        die();
    }
    echo "Beginning copy. \n";
    imap_mail_copy($this->mbox, $IDsequence, $TargetFolder);
    echo "Copy complete. \n";
    //imap_expunge($this->mbox);
    imap_close($this->mbox);
//获取收件箱中的所有邮件
$mail=imap_搜索($this->mbox,“ALL”);
如果(!$mail){echo“收件箱是空的。\n;die();}
//创建所有消息ID的字符串列表
//在指定范围内
$processed=0;
$IDsequence='';
foreach($mail as$messageID)
{
$date=imap_headerinfo($this->mbox,$messageID)->date;
试试{$dateObject=newdatetime($date);}
捕获(异常$e){echo$e->getMessage();echo“\n”}
$dateObject->setTimezone($TimeZone);
如果($dateObject=
$IntervalsStartDate)
{
$IDsequence=$IDsequence.,“.strval($messageID);
}
$processed=$processed+1;
如果($processed%100==0)
{echo“已处理$Processed电子邮件。\n”;}
}
//如果我们至少收到一条消息,请删除第一个逗号。
如果(strlen($IDsequence)>1){
$IDsequence=substr($IDsequence,1,strlen($IDsequence)-1);
}
其他的
{
回显“没有要移动的电子邮件。\n”;
模具();
}
回显“开始复制。\n”;
imap\u邮件副本($this->mbox,$IDsequence,$TargetFolder);
回显“复制完成。\n”;
//imap炣expunge($this->mbox);
imap_关闭($this->mbox);
在遍历了25000多封电子邮件之后,它开始打印错误消息“object not existence”,引用我从电子邮件标题收集日期的代码行。我在这里注意到,崩溃仍然发生在25000封电子邮件左右,因此,可能两种方法都因为相同的原因而崩溃。我怀疑我的邮件ID有问题(例如,我假设75000封电子邮件的邮件ID为“1”到“75000”)


出什么事了?有没有办法收集大量在某个日期范围内的电子邮件并将其移动?

也许邮箱中只有25112封邮件,而其他~50000封邮件则在另一个邮箱中。例如,我知道GMail可能会报告收件箱的大致总数,但这些邮件中有很大一部分实际上是存档的


此时,您可能需要进行一次健全性检查。:)

我想这里不是这样的。我计算了运行imap_搜索时返回的元素($mbox,“ALL”),并计算了收件箱的完整大小。我猜当我试着按日期排序时,事情在25000左右开始出错。