【问题标题】:why the program can't stop after downloaded all the emails?为什么下载所有邮件后程序无法停止?
【发布时间】:2015-09-06 03:52:55
【问题描述】:

我的 gmail 中有 2465 封邮件,为什么下载所有邮件后程序无法停止?所有 code1 和 code2 都在命令行模式下运行。
代码1:

<?php
$mailbox = array(
    'mailbox'  => '{imap.gmail.com:993/imap/ssl}INBOX',
    'username' => 'xxxx@gmail.com',
    'password' => 'yyyy'
);

$stream = imap_open($mailbox['mailbox'], $mailbox['username'], $mailbox['password'])
    or die('Cannot connect to mailbox: ' . imap_last_error());
$emails = imap_search($stream,"ALL");
$nums=imap_num_msg($stream);
echo $nums;
foreach($emails as $email_id) {

            $mime = imap_fetchbody($stream, $email_id, "");
            file_put_contents("/tmp/" . "email_{$email_id}.eml", $mime);
        }

imap_close($stream);
echo "over";
?>

对于代码 1:
1.可以下载所有邮件。
2.控制台输出2465
3.控制台没有over输出。
4.程序不能停止,它似乎永远运行。

代码2:

<?php
$mailbox = array(
    'mailbox'  => '{imap.gmail.com:993/imap/ssl}INBOX',
    'username' => 'xxxx@gmail.com',
    'password' => 'yyyy'
);

$stream = imap_open($mailbox['mailbox'], $mailbox['username'], $mailbox['password'])
    or die('Cannot connect to mailbox: ' . imap_last_error());
$emails = imap_search($stream,"ALL");
$nums=imap_num_msg($stream);
echo $nums;
foreach($emails as $email_id) {
            echo  $email_id.PHP_EOL;
            $mime = imap_fetchbody($stream, $email_id, "");
            file_put_contents("/tmp/" . "email_{$email_id}.eml", $mime);
        }

imap_close($stream);
echo "over";
?>

对于代码 2:
1.可以下载所有邮件。
2.控制台输出2465 .
3.over在控制台输出。
4.下载所有邮件后程序停止。

code2比code1多了一行echo $email_id.PHP_EOL;,其他代码相同。
所有 code1 和 code2 都在命令行模式下运行。
谁能解释一下?

【问题讨论】:

  • 你说什么都不做就挂了?只要 CPU 不是 100%,它可能会挂在某个系统调用中……然后尝试 strace 并查看最后一个系统调用是什么。
  • 尝试设置超时以使用 imap_timeout 获取电子邮件 - 您的回声可能会意外地使第二个脚本超时。
  • 你还能重现错误吗?如果是这样,您使用的是什么 php 版本,执行脚本时使用的是什么 shell?
  • 您是否尝试打印$emails 数组或查看它的计数以确保其中没有任何空白条目?
  • 您如何连接到实际运行脚本的机器?如果它是远程的,则可能是 stdio(终端连接)上的不活动,同时它在远程计算机上获取和下载消息,超过了您的连接超时。考虑到在代码 2 中“结束”需要多长时间,您能否将单独的窗口连接到运行代码 1 的机器,并在相同的时间后查看进程是否实际上仍在运行。同样检查脚本时间限制,在 php_cli

标签: php email


【解决方案1】:

试试

print imap_last_error();

imap_close 之前和之后,了解更多关于导致您的问题的原因

【讨论】:

    【解决方案2】:

    检查imap_fetchbody() 功能,此功能允许您设置下载限制,并且您可以在所有邮件下载后停止。检查下面的代码,我对您的代码进行了一些更改,这些更改将在所有邮件下载后停止下载过程。请检查一次。

    <?php
    $mailbox = array(
        'mailbox'  => '{imap.gmail.com:993/imap/ssl}INBOX',
        'username' => 'xxxx@gmail.com',
        'password' => 'yyyy'
    );
    
    $stream = imap_open($mailbox['mailbox'], $mailbox['username'], $mailbox['password'])
        or die('Cannot connect to mailbox: ' . imap_last_error());
    
    //Check all mails...
    $imap_obj = imap_check($stream);
    
    // Fetch an overview for all messages in INBOX...
    $nums=imap_num_msg($stream);
    $emails = imap_fetch_overview($stream,"1:{$imap_obj->Nmsgs}",0);
    
    echo $nums;
    //Loop until mail data...
    foreach($emails as $objEmail_data) {
        $mime = imap_fetchbody($stream, $objEmail_data->msgno, "");
        file_put_contents("/tmp/" . "email_{$objEmail_data->msgno}.eml", $mime);
    }
    
    imap_close($stream);
    echo "over";
    ?>
    

    然后看看结果!

    我将imap_search() 替换为imap_fetch_overview() 并进行了一些相关更改。

    如果需要任何进一步的帮助,请告诉我。

    【讨论】:

    • 我已经测试了各种状态。
    • 所有代码,我的代码1代码2和AddWeb Solution Pvt Ltd'代码可以用putty运行来连接我的vps,在命令行模式和浏览器模式下都可以得到相同的结果。本地操作系统是windows,服务器操作系统是debian7。
    • 本地操作系统是debian7,服务器操作系统是debian7,我的code1在浏览器模式下运行,得到想要的结果。当我的code1在命令行模式下运行时,下载所有电子邮件后无法停止。
    • 所以,我得出的结论是debian7上的休眠问题,程序运行了这么长时间,没有任何输出导致debian控制台休眠,直到所有电子邮件下载完成,它无法唤醒。
    • 在我的 debian7 上禁用休眠的方法仍然存在一些错误。
    【解决方案3】:
    <?php
    $mailbox = array(
        'mailbox'  => '{imap.gmail.com:993/imap/ssl}INBOX',
        'username' => 'xxxx@gmail.com',
        'password' => 'yyyy'
    );
    
    $stream = imap_open($mailbox['mailbox'], $mailbox['username'], $mailbox['password'])
        or die('Cannot connect to mailbox: ' . imap_last_error());
    $emails = imap_search($stream,"ALL");
    $nums=imap_num_msg($stream);
    //echo $nums; // removed this
    foreach($emails as $email_id) {
    
                $mime = imap_fetchbody($stream, $email_id, "");
                file_put_contents("/tmp/" . "email_{$email_id}.eml", $mime);
            }
    unset($emails); // added this
    imap_close($stream);
    die ("over"); // changed this
    ?>
    

    我已重置电子邮件变量。

    【讨论】:

    • 问题的关键在于它永远不会离开foreach 循环。
    猜你喜欢
    • 1970-01-01
    • 2022-01-05
    • 1970-01-01
    • 2020-05-31
    • 1970-01-01
    • 2021-10-31
    • 1970-01-01
    • 2021-11-05
    • 1970-01-01
    相关资源
    最近更新 更多