如果我有一个填写表单的用户数据库,我可以使用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作业通过检查下一个是哪一个来处理其余部分?
答案 0 :(得分:0)
这是一个非常好的方法。它只会在每条记录中发送一次(因此假设您在已完成的表中没有重复项)。
我假设您正在更新循环中的valuesent字段
答案 1 :(得分:0)
我建议:
您确保您的completed
表使用事务存储引擎,例如InnoDB的:
ALTER TABLE completed ENGINE=InnoDB;
您定义一个新的BOOLEAN
列,指示(对于任何其他数据库连接)给定记录正在更新过程中:
ALTER TABLE completed ADD COLUMN updating BOOLEAN NOT NULL DEFAULT FALSE;
您使用locking read到SELECT
要通过电子邮件发送的记录,然后在{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();
然后,您可以在发送每封电子邮件时更新数据库(删除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']));
}
请注意,如果脚本过早终止,则数据库可能处于不合需要的状态,即。记录可能有updating=TRUE
但不再有任何脚本处理它们;这可能导致一些记录没有通过电子邮件发送。您可能希望通过registering a custom shutdown function防止这种可能性,或者通过定期检查数据库中的“孤立”记录(但是您当然必须确保它们当前没有被正在运行的脚本处理)。 / p>