【问题标题】:Prevent Multiple Entries using PHP使用 PHP 防止多个条目
【发布时间】:2011-12-27 07:34:47
【问题描述】:

与网页上的投票设施一起显示的是以下输入字段,访问者(选民)可以在抽奖中输入他们的详细信息,作为对他们参与投票的奖励的奖励。

抽奖表格脚本未附加到投票脚本。抽奖输入表单脚本中的所有输入都经过验证,并将信息发送到平面文件。这是一项仅持续 7 天的简短民意调查,针对小镇论坛可能不时出现的不同主题。 (ip也被收集)

Name  :<input type="text" name="visitor" /><br /><br />
Email :<input type="text" name="visitormail" /><br /><br />
Phone :<input type="text" name="visitorphone"/><br /><br />

提交时,“谢谢”页面会告知访问者他们的详细信息将在抽奖活动中一次用于礼篮。换句话说,访问者可以返回并再次填写表格并提交,要求我在完成随机数抽奖之前检查并清除平面文件中的多个条目!

问题有没有一种简单的方法来安装一些东西来防止访问者尝试多次进入抽奖?

【问题讨论】:

  • 您是否先以用户身份登录?
  • 禁止登录 - 试图为普通玩家维护简单的访问权限。另外,暂时不想超越自己的技能。
  • 有多人参加抽奖有这么大的问题吗?你怎么知道他们没有在你的投票中多次投票?
  • 目前使用每个 ip 一票管理多个投票条目。但是在过去的半个小时里,我学到了很多关于 ip 的知识。正如您所指出的,没有一个可以解压和插入的简单解决方案。

标签: php forms flat-file multiple-entries


【解决方案1】:

我同意@David Barker 的观点,除非您将他们登录并拥有他们的用户 ID,否则人们可能会找到解决您放置的任何内容的方法。但是,我不同意他的答案是“是”。我认为答案是否定的。

我看不出有任何方法可以阻止访问者在多个条目中提交略有不同的信息。除非您要求并验证他们的社会保障、护照或驾驶执照号码。事实上,避免在一个系统上登录多个帐户也是如此。

因此,您可能不得不接受人们可能会多次参加抽签或放弃抽签。

很抱歉给出否定的答案,但如果没有大量资源可供您使用,我真的看不出如何实现您想要的目标。

编辑以进一步解释我的论点:

1 - 使用名称作为过滤器

我有一个简单的名字“Paul White”,Paul Whites 有数千甚至数百万,因此仅限于一个是不现实的。

2 - 使用 IP 地址

我所要做的就是断开我的路由器与我的 ISP 的连接,然后重新连接。你好,新IP,第二次进入抽奖。或者登录到我老妈妈的电脑——同样的结果。你不能阻止多个条目,句号。

3 - 使用电话号码

我还有两部手机,一个固定电话号码和一个 Skype 号码(我经常出差),我每次可以使用不同的。

4 - 使用门牌号加邮政编码

在英国(我不知道其他任何地方,但怀疑是相似的)一个邮政编码适用于许多房屋。但是,假设我的门牌号是 16,我可以提交一个 16、16a、16b... 的条目,并且地址仍然有效,邮寄给它的任何东西都会寄给我。

5 - 与您能想到的任何其他事情的细微操作有关的类似论点

【讨论】:

  • vascowhite 你让我几乎信服了。应该将地址也带入图片中,并且会有所帮助!人们会为了一个篮子做出这样的努力吗?
  • 一个有效的地址可以有不同的写法,看看你家门口的垃圾邮件就知道了!对于您的其他问题:- 是否应该为一个篮子做出这样的努力?
  • 礼篮可能没有抽奖活动!也许我应该在“谢谢”页面上添加一个“圣诞愿望”。
【解决方案2】:

您可以使用电子邮件作为密钥轻松解决此问题。如果您使用的是数据库,则可以快速检查电子邮件是否存在,例如

"SELECT COUNT(visitoremail) FROM users WHERE LOWER(visitoremail) = '" . strtolower($_REQUEST['visitormail']) . "';

如果结果大于零,则不会将它们添加到数据库中。同样,如果计数等于 0,那么您将对新数据执行 INSERT。

另一种方法是将所有条目存储在数据库中。然后,要么 "SELECT DISTINCT visitoremail FROM users ..." 要么选择所有电子邮件到 PHP 数组中,然后执行 array_unique(visitoremails) 以获取唯一的电子邮件。

【讨论】:

  • 另外,如果您使用的是平面文件,然后在比赛结束时将所有电子邮件放入一个数组中,那么使用 array_unique 获取唯一性肯定会满足您的需求。
  • 我有 6 个电子邮件地址?事实上,如果我使用 + 号添加地址标签this is not limited to gmail,则无限制
  • 是否也可以像您在上面的电子邮件键中设置的那样使用电话,以便根据两条记录检查输入?
  • 我还有两部手机,一个固定电话号码和一个Skype号码(我经常出差),我每次可以使用不同的。很抱歉是否定的,但请看我的回答。
  • 我有 10 个域,带有 cathcall 地址,所以我有 10 * 无限制地址,电子邮件不是那么独特
【解决方案3】:

答案是肯定的,但你只能用你提供的数据来阻止人们。人们(如果愿意)会找到一种方法让自己多次参加比赛。

如果键输入数据与文件中已保存的数据匹配,我将有一个从平面文件中读取并返回 true 的脚本。

例如

$input = $_REQUEST['post_data'];

$fp = fopen("poll.txt","r");

while ($ln = fgetcsv($fp, 1000, "\t") !== FALSE) {
    if ($ln[4] == $input['post_data']) {

        // Set exists to true
        $exists = TRUE;
    }
}

// Check if $exists == TRUE {
//     return false;
// Else {
//     write new data to file.
// }

这认为您的平面文件由/t 为每个“单元格”分隔。 还要考虑:$ln[x],其中 x = 文件每一行的数据位置。

【讨论】:

  • 对不起,大卫,答案是“不”,看我的回答。 :)
  • 平面文件目前是这样的:fwrite($out,"$todayis [IST], $vname, $vemail, $vphone, $ip, $httpref, $httpagent."); 2011 年 11 月 11 日,星期五,晚上 7:47 [IST],ffffff ffffffff,ffff@mmmmmmmm.jh,55555555555,127.0.0.1,localhost/Poll/DRBPoll/booth.php,Mozilla/5.0(Windows;U;Windows NT 6.1;en-GB; rv:1.9.2.23) Gecko/20110920 Firefox/3.6.23.
【解决方案4】:

如果用户必须登录才能投票,那么您只需保存 user_id 并检查他们是否已经投票。或者,如果他们是匿名的,您可以检查 IP 号码$_SERVER['REMOTE_ADDR ']。或者,您可以在提交时保存一个 cookie。

【讨论】:

  • IP 对此没有好处,因为它们可能会发生变化,或者您可能有多个计算机/用户在使用 NAT 的 1 个 IP 后面。
  • 每个 IP 一票,让一名学生在学校的每台连接互联网的计算机上投票一次,如果不在 NAT 路由器后面,如果在 NAT 路由器后面,则每个学校/公司一票
  • 一票由ip控制,没问题。抽奖输入是单独的 - 与投票脚本没有实际连接。尽量防止多人参与抽奖。
  • 我所要做的就是断开我的路由器与我的 ISP 的连接,然后重新连接。你好,新IP,第二次进入抽奖。或者登录到我老妈妈的电脑——同样的结果。您不能阻止多个条目,句号。
【解决方案5】:

我也会记录 IP(请参阅$_SERVER 变量)。然后,您可以按 IP 缩小重复范围。并不总是最简单的方法。

另一种方法可能是 cookie。

【讨论】:

  • Cookie 很容易受到用户操纵,但将 IP 存储在您的数据库/平面文件后端会消除他们操纵您的守门的能力。
  • cookie 有用吗!对cookies还不是很熟悉。我注意到您的补充评论。
  • 大多数学校和公司都有一个公用IP,所以每个ip一个wote等于千个地方每个学校/公司一个wote,并且每台计算机有一个ip的学校,单个用户可以从每台机器上写一次
  • 一票由ip控制,没问题。抽奖输入是单独的 - 与投票脚本没有实际连接。
  • 您也可以使用微软的方法,编写一个程序,根据您的硬件等生成指纹。强制您的用户激活他们的抽奖活动! (大声笑和 TROLOLOLOL)
【解决方案6】:

我假设您正在将数据存储到数据库中。然后你可以选择一个项目,它必须是唯一的(我推荐一个电话号码)并将其列设置为唯一键。因此多次插入数据库会失败(您必须事先检查电话号码格式并在实际插入之前对其进行标准化,但这是完全不同的问题)。

【讨论】:

  • 是的 Erbureth,数据会在线而不是 cols 传输到平面文件数据库...使用电话 no 似乎是个好方法!您的解决方案是否适用于平面文件?
  • 如前所述,它依赖关系数据库引擎来保证记录的唯一性。然而,一般的想法可以实现到文本平面文件,但是你需要自己做完整性和唯一性检查。我真的建议使用基于 SQL 的引擎来存储数据。
  • 我很感激需要长期加入 SQL 引擎。我认为目前我被扁平引擎卡住了。
  • 那么你需要自己检查相应的字段,但是要做好准备,没有任何索引会很慢。此外,您需要确保一次对一个线程的文件的独占访问,否则它会遭受数据丢失或损坏。例如,您可以通过创建一个“锁定文件”来完成它,它代表正在访问的文件。
  • 您可以通过使用 x 标志调用 fopen 来创建锁定文件 --php.net/manual/en/function.fopen.php
【解决方案7】:

如果您在 onclick 事件中禁用提交按钮,访问者将不得不刷新页面以重新提交您的表单。

你可以这样做:

var btn = document.getElementById("button-id");
btn.onclick = function() {
    btn.disabled = 'disabled';
}

【讨论】:

  • 实际上所有访问者需要做的就是关闭javascript。我认为这根本不能回答问题。
  • 好的,gustavotkg,如果访问者在一两天后返回到刷新的页面,他们是否能够再次将他们的详细信息提交到平面文件?
  • 但是你的建议确实让我思考!谢谢。
猜你喜欢
  • 2014-09-18
  • 1970-01-01
  • 2011-07-04
  • 2014-10-12
  • 1970-01-01
  • 2015-02-13
  • 1970-01-01
  • 1970-01-01
  • 2014-08-13
相关资源
最近更新 更多