【问题标题】:How to prevent a cronjob foreach loop from sending an email to EVERY result row?如何防止 cronjob foreach 循环向每个结果行发送电子邮件?
【发布时间】:2018-01-27 13:58:37
【问题描述】:

我有一个 cron 作业,它查看表格并相应地发送电子邮件。

表格非常简单,只需:

  • cronid(自增主键id)
  • groupid(用户所在组的id)
  • 已发送(默认为0,cron-job运行后将更新为1)

脚本(如下)查找所有带有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]);
}

我有 4 个条目与 sent=0 相同的组号,所以我假设上面的代码将发送第一封电子邮件,然后最后一个查询将使用该组号更新所有其他行以具有 sent = 1,因此它不会发送其他 3。但我测试并发送了 4 封单独的电子邮件。

我花了一分钟才意识到(我知道,非常愚蠢)原始查询和 foreach 循环会立即找到所有 4 行,然后我们会循环遍历这 4 行,而不管循环期间所做的任何更改。因此,即使我在发送第一封电子邮件后将其他 3 行的 sent 更新为 1,它仍将完成对原始查询结果的循环(即所有 4 行)并发送 4 封电子邮件。

所以我现在的问题是,我如何设置它来搜索所有具有 sent = 0 但每个组号仅发送一封电子邮件的行。我在想也许我在原始查询中使用 GROUP BY 或 UNIQUE ?我在正确的轨道上吗?

【问题讨论】:

    标签: php mysql email cron


    【解决方案1】:

    你在正确的轨道上。

    在第一个查询中添加GROUP BY

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

    然后在循环内的查询中向 WHERE 语句添加另一个条件,以确保您没有更新已经正常的记录。

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

    我不确定您运行 cronjob 的频率以及需要多长时间,但现在您可能会更新已添加的记录,然后再检索它们。

    【讨论】:

    • 谢谢,我会添加 GROUP BY。关于你最后的想法,它可能会每分钟运行一次。您是说此设置可能会在我检索到原始结果集后更新刚出现的新条目?
    • 是的,这是可能的,但是否重要取决于你:-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-28
    • 2021-07-04
    • 1970-01-01
    • 2015-05-15
    相关资源
    最近更新 更多