CRON Job向DB中的用户发送电子邮件?

时间:2015-03-07 12:23:13

标签: php mysql email cron

如果我有一个填写表单的用户数据库,我可以使用cron作业发送自动电子邮件吗?如果是这样,那么"循环"的最佳方式是什么?它,以便它向每个用户发送一次电子邮件?

$data = mysql_query("
SELECT *
FROM completed
WHERE
followupsent='0000-00-00 00:00:00'
AND valuesent + INTERVAL 4 DAY <= NOW()
")
or die(mysql_error()); 

while($info = mysql_fetch_array( $data )) 
{
}

这将检查&#34; followupsent&#34;已经更新,因为它在发送时使用NOW()进行更新,并且还会检查自发送值以来的天数。

我担心通过将电子邮件发送到while标签中的信息将为每一行循环播放并最终发送大量电子邮件。

使用和if代替while

if($info = mysql_fetch_array( $data )) 
{
}

为了发送到数据库中的第一个,然后让cron作业通过检查下一个是哪一个来处理其余部分?

2 个答案:

答案 0 :(得分:0)

这是一个非常好的方法。它只会在每条记录中发送一次(因此假设您在已完成的表中没有重复项)。

我假设您正在更新循环中的valuesent字段

答案 1 :(得分:0)

我建议:

  1. 您确保您的completed表使用事务存储引擎,例如InnoDB的:

    ALTER TABLE completed ENGINE=InnoDB;
    
  2. 您定义一个新的BOOLEAN列,指示(对于任何其他数据库连接)给定记录正在更新过程中:

    ALTER TABLE completed ADD COLUMN updating BOOLEAN NOT NULL DEFAULT FALSE;
    
  3. 您使用locking readSELECT要通过电子邮件发送的记录,然后在{em>同一交易中由UPDATE添加到新的创建了专栏。例如,使用PDO

    $dbh->beginTransaction();
    
    $select = $dbh->query('
      SELECT *
      FROM   completed
      WHERE  followupsent IS NULL
         AND valuesent <= CURRENT_TIMESTAMP - INTERVAL 4 DAY
         AND NOT updating
      FOR UPDATE
    ');
    
    $dbh->exec('
      UPDATE completed
      SET    updating = TRUE
      WHERE  followupsent IS NULL
         AND valuesent <= CURRENT_TIMESTAMP - INTERVAL 4 DAY
         AND NOT updating
    ');
    
    $dbh->commit();
    
  4. 然后,您可以在发送每封电子邮件时更新数据库(删除updating标记以及您需要的任何其他状态):

    $success = $dbh->prepare('
      UPDATE completed
      SET    followupsent = CURRENT_TIMESTAMP,
             updating = FALSE
      WHERE  id = ?
    ');
    
    $failure = $dbh->prepare('
      UPDATE completed
      SET    updating = FALSE
      WHERE  id = ?
    ');
    
    foreach ($select as $row) {
      $command = mail(...) ? $success : $failure;
      $command->exec(array($row['id']));
    }
    
  5. 请注意,如果脚本过早终止,则数据库可能处于不合需要的状态,即。记录可能有updating=TRUE但不再有任何脚本处理它们;这可能导致一些记录没有通过电子邮件发送。您可能希望通过registering a custom shutdown function防止这种可能性,或者通过定期检查数据库中的“孤立”记录(但是您当然必须确保它们当前没有被正在运行的脚本处理)。 / p>