2017-08-18 3 views
0

私はテーブルを見てそれに応じて電子メールを送るcronジョブを持っています。デフォルトで送信cronjob foreachループがすべての結果行に電子メールを送信しないようにするにはどうすればいいですか?

  • cronid(自動インクリメントの主キーID)
  • グループID(グループIDは、ユーザがである)
  • (0:

    テーブルだけと非常に簡単です

スクリプトは、sent = 0のすべての行を見つけ、電子メールを送信するためにループスルーします。

//find all instances of a hunch being submitted that haven't yet had notification emails sent, and loop thru and send emails 
$stmt = $pdo->prepare("SELECT cronid, groupid FROM cron_email_notify WHERE sent = 0 "); 
$stmt->execute(); 
foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) { 
    $cronid=$row['cronid']; 
    $groupid=$row['groupid']; 

    //phpmailer stuff to actually send emails goes here, not relevantto this question 

    //update cron_email_notify table's sent field to 1, so we know not to send again 
    $stmt = $pdo->prepare("UPDATE cron_email_notify SET sent = 1 WHERE groupid = ?"); 
    $stmt->execute([$groupid]); 
} 

私は= 0 sentと同じグループ番号のための4つのエントリを持っていたので、私は上記のこのコードは最初にメールを送ってしまうと仮定し、最後のクエリは= sentを持つように、そのグループ番号を持つ他のすべての行を更新します1、それゆえ、それは他の3を送信しませんでした。しかし私はテストし、4つの別々の電子メールが送信されました。

元のクエリとforeachループがすぐに4行すべてを見つけて、私たちがループ中に行った変更にかかわらず、それらのループを4回繰り返していることを分かりました。したがって、最初の電子メールが送信された後、他の3行に対してsentが1に更新されたとしても、元のクエリ結果(つまり4行すべて)をループして終了し、4つの電子メールを送信することになりました。

これで、sent = 0のすべての行を検索するように設定できますが、グループ番号ごとに1つのメールだけを送信します。元のクエリでGROUP BYまたはUNIQUEを使用していると思いますか?正しい軌道にいるのですか?

答えて

1

あなたは正しい道を歩いています。

あなたが出回っ大丈夫ですレコードを更新していないことを確認するためにWHERE文の最初のクエリ

$stmt = $pdo->prepare("SELECT cronid, groupid FROM cron_email_notify WHERE sent = 0 GROUP BY groupid"); 

してからループ広告内のクエリ別の条件でにGROUP BYを追加します。

$stmt = $pdo->prepare("UPDATE cron_email_notify SET sent = 1 WHERE groupid = ? AND sent = 0"); 

私はあなたがcronジョブとどのくらいの時間がかかりますが、それは今、あなたはあなたがそれらを取得しているとき、後で、その後追加されたレコードを更新することができている方法を実行する頻度はわかりません。

+0

ありがとう、私はGROUP BYを追加します。あなたの最後の考えについては、毎分実行する可能性が高いです。元の結果セットを取得したあと、この設定で新しいエントリが更新される可能性がありますか? – user3304303

+1

うん、それは可能かもしれませんが、それは重要であるかどうかはあなた次第です:-) –

関連する問題