0

コントローラのcodeigniterメソッドで受信者情報を取得するためにforeachループを使用してメールを送信しています。メールが送信された場合は、受信者テーブルの受信者ステータスを「送信済み」に更新します。

同じコントローラーの別の方法(同じモデルを使用)では、未送信のメールの数を取得しますが、送信中に未送信のメールの数を取得しようとすると、foreachループが完了するまで待機します。

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です

4

3 に答える 3

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();
于 2012-11-08T16:09:25.957 に答える
0

データベースに未送信メールの数を保持し、クエリを使用して取得することをお勧めします。

于 2012-11-08T15:48:09.697 に答える
0

PHP クラス インスタンスはリクエストごとに作成されるため、実行中に情報を取得できるようにする場合は、MySQL のテーブルにデータを書き込むか、 または などを使用する必要がありMemcachedますAPC

于 2012-11-08T15:48:58.963 に答える