我正在使用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
答案 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();