如何检测同一封电子邮件是不是在 2 分钟内多次出现?

Posted

技术标签:

【中文标题】如何检测同一封电子邮件是不是在 2 分钟内多次出现?【英文标题】:How can I detect if the same email appears more than once within 2 minutes?如何检测同一封电子邮件是否在 2 分钟内多次出现? 【发布时间】:2013-01-23 13:08:17 【问题描述】:

如何检测同一封电子邮件是否在 2 分钟内出现多次。

这是我的输出:

07-02-13 20:08:41   test11@gmail.com
07-02-13 20:09:41   test11@gmail.com
07-02-13 20:21:25   hottie@gmail.com
07-02-13 20:56:51   ugly@gmail.com
07-02-13 21:42:37   selma532@gmail.com
07-02-13 22:09:11   blalbla421@gmail.com

这是我的 SQL 语句。

$results = $this->EE->db->query("SELECT t.* FROM transactions as t WHERE t.cardid > 0 ORDER BY t.created DESC");

我希望他们将她分开。因此,如果相同的邮件在 2 分钟内出现,则必须进行不良交易。

foreach ($results->result_array() as $filter) 

我可以帮忙:我有一个 $filter['created'] = 这包含时间,我有一个 $filter['email'] )这包含电子邮件。

if(//Filter goes here) 
  $badtransactions[]=$filter;
 else 
  $cooltransactions[]=$filter;

这是我的

<table class="table">
  <h3>Cool Transactions (<?php print_r($sizeCoolTransactions)?>) </h3>
  <thead>
    <tr>
      <th>Time</th>
      <th>Email</th>
    </tr>
  </thead>
  <tbody>
    <?php
    //Foreach over cooltransactions
    foreach($cooltransactions as $transaction) 

      // IS NEW?
      $isactive = false;
      if($transaction['created'] > time()-$refresh_timer)
        $isactive = true;
      

      // Get user mail.
      $member_sql = $this->EE->db->query("SELECT email FROM exp_members WHERE member_id = '".($transaction['cardid']-10000000)."'");

      $member_result = $member_sql->result_array();
      if(isset($member_result[0])) 
        $member_result1 = $member_result[0];
      
    ?>
    <tr class="<?= $isactive ? 'alert-success' : ''; ?>">

      <td><?= date('d-m-y H:i:s', $transaction['created']); ?></td>
      <td><?= isset($member_result1['email']) ? $member_result1['email'] : '<span style="color:red">Email mangler</span>'; ?></td>
    </tr>
    <?php
      
    ?>
  </tbody>
</table>

【问题讨论】:

不久前我有一个非常相似的问题。我认为答案适用于你:***.com/a/6556239/362536 它没有帮助我。 :/ 我希望 min 分成两个事务。因此,如果电子邮件在 2 分钟内再次出现 = 错误交易。否则,很酷的交易。 ...但是在 if 语句中写什么是个大问题 你可以缓存东西,以获得一些速度,查询数据库我认为比缓存东西需要更长的时间。另一种方法是检查当差异大于 2 分钟时创建具有相同电子邮件的条目然后忽略第一封邮件或其他任何内容。 @GeoPhoenix,你会怎么做?如果可以的话,你可以试试我上面发布的代码吗? 您真的不应该对卡 ID 进行骇人听闻的“调整”以将其转换为会员 ID - 如果可能,请找到实际映射它的方法。此外,即使您在这里可能不接受 SQL 注入,最好还是使用参数化查询,以保证您未来的安全并保持一致。你在这里的最终目的是什么?您正在将信息显示到页面,但您是否需要主动拒绝上传或其他内容?进行存在性检查相当简单...... 【参考方案1】:

这就是你要找的吗?不幸的是,它是为 MSSQL 编写的,但希望您可以更改语法以使用您的 RDBMS。

基本上设置您的当前时间(我默认它以适应提供的数据)并使用 DATEADD() 创建一个范围。查询日期时间在过去 2 分钟内为您提供所有电子邮件的范围内的哪个位置。最后将其包装在 GROUP BY Email HAVING COUNT(*) > 1 中以显示所有重复项。

http://sqlfiddle.com/#!3/1d759/17

【讨论】:

关闭@deeg。您正在 SQL 语句中过滤它,这很好。但我希望它在 if 语句中执行,这样我就可以在 2 分钟内出现相同的电子邮件 = 错误交易和其他很酷的交易。【参考方案2】:

您可以编写如下所示的 SQL 查询。基本上所有这些都是,对于数据库中返回的每一行,检查同一个表中具有该电子邮件地址的条目以及大于 -2(过去两分钟)的日期时间字段(在本例中为 Created)上的 timediff 和+2(未来两分钟)。如果在当前记录的两分钟内找到一条记录,它会将 OccursWithinTimescale 字段值设置为匹配记录的 id 的值。因此,如果 OccursWithinTimescale 为空,则该电子邮件在两分钟内没有出现在表中,否则它已经出现,并且您有违规记录的 id。

select l1.id, created,
(select max(id) from log where email = l1.email 
    and (
            (minute(timediff(created, l1.created)) <= 2 and minute(timediff(created, l1.created)) >= -2)
        ) 
    and id <> l1.id
    and date(created) = date(l1.created)
) as OccursWithinTimescale, 
l1.email from log l1 

使用这种方法有一些限制,因为我没有包含任何关于索引的内容,您需要使用这种子查询来研究这些内容。此外,如果在大型数据集上使用子查询,可能会消耗大量资源。但这至少是一个选择,虽然可能不是最好的。

您可以通过在 OccursWithinTimescale is not null 上添加 where 子句来进一步调整该查询以仅返回在两分钟内发生的所有记录。

【讨论】:

以上是关于如何检测同一封电子邮件是不是在 2 分钟内多次出现?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Mailchimp API 3.0 多次向订阅者发送同一封电子邮件

在 MailChimp 中多次发送活动

HTML 电子邮件正文是不是可以引用作为附件发送的文件(在同一封电子邮件中)?

邮箱每天上限

Spring 定时器调用 mail.jar 定义每10分钟检查是不是要发邮件。邮件发送2个一样的。

一个PHP程序,同一时刻被请求多次,怎么让它只运行一次?