在foreach运行时获取行数

时间:2012-11-08 15:46:30

标签: php mysql codeigniter

我正在使用foreach循环发送邮件,以便在控制器的codeigniter方法中获取收件人信息,并且,如果邮件被发送,我将收件人表中的收件人状态更新为“已发送”。

在同一个控制器的另一个方法中(使用相同的模型),我得到了未发送邮件的数量,但是如果我在发送邮件时尝试获取未发送邮件的数量,它会等到foreach循环完成。< / p>

如果在foreach循环中发送这些邮件,我怎样才能连续获取未发送的邮件数量?

recipients table
    id int 11
    recipient_id int 11
    mail_id int 11
    sent tinyint 1
    failed tinyint 1

$recipients = $this->MMails->GetRecipients($mail_id);
foreach($recipients as $recipient) {
    //send message using swift
    if($message_sent) {
        $this->MMails->MarkAsSent($recipient_id);//this recipient table gets updated actually, but I can't read the new COUNT value until this loop finished
    }
}

来自模特:

 function GetNumOfQueued() {//Get number of queued mails
    $query = $this->db->query("SELECT COUNT(id) as num_of_queued
        FROM recipients 
        WHERE sent = 0");
    return $query->row()->num_of_queued;
}//GetNumOfQueued

 function MarkAsSent($recipient_id) {//Update mail recipient status to sent
    $this->db->set('sent', 1);
    $this->db->where('id', $recipient_id);
    $this->db->limit(1);
    $this->db->update('recipients');

}//MarkAsSent

简单地说,PHP在循环结束之前不会响应,并且在循环处于活动状态时我无法在应用程序中打开任何其他页面。

我本地php.ini中的设置是output_buffering = Off

3 个答案:

答案 0 :(得分:0)

我建议将未发送邮件的数量保留在数据库中,并使用查询获取。

答案 1 :(得分:0)

每个请求都会创建PHP类实例,因此如果您希望在信息仍在运行时能够获取信息,则需要将数据写入MySQL中的表或使用Memcached或{ {1}}。

答案 2 :(得分:0)

你不能只使用一个柜台吗?

$recipients = $this->MMails->GetRecipients($mail_id);
$messages_to_send = count($recipients);
foreach($recipients as $recipient) {
    //send message using swift
    if($message_sent){
        $messages_to_send--; 
        $this->MMails->MarkAsSent($recipient_id);
    }
}

输出缓冲应该可以解决问题:

http://php.net/manual/en/book.outcontrol.php

循环运行时允许其他执行。

以下是处理循环时在屏幕上输出ob的示例:

if (ob_get_level() == 0) ob_start();

for ($i = 0; $i<10; $i++){

        echo "<br> Line to show.$i";
        echo str_pad('',4096)."\n";    

        ob_flush();
        flush();
        sleep(2);
}

echo "Done.";
ob_end_flush();

-http://us1.php.net/manual/en/function.flush.php#54841


if (ob_get_level() == 0) ob_start();

$recipients = $this->MMails->GetRecipients($mail_id);
$messages_to_send = count($recipients);
foreach($recipients as $recipient) {
    //send message using swift
    if($message_sent){
        $messages_to_send--; 
        $this->MMails->MarkAsSent($recipient_id);
        echo "<br> Emails left to send: .$messages_to_send";
        echo str_pad('',4096)."\n";    
        ob_flush();
        flush();
    }
}
echo "All emails have been sent.";
ob_end_flush();