Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP/MYSQL只允许每个成员投一票?_Php_Mysql_Voting System - Fatal编程技术网

PHP/MYSQL只允许每个成员投一票?

PHP/MYSQL只允许每个成员投一票?,php,mysql,voting-system,Php,Mysql,Voting System,我一直在做建立奖项投票系统的工作,我对php和mysql不太了解。但我比这里的任何人都了解这一点,我的老板也在度假。但我一直在重用以前留在我们系统上的代码,并在今年对其进行了调整 基本上,投票系统工作正常,我在mysql中设置了新的表来捕获数据。不过,我在现有代码中发现了一个相当大的缺陷,不知道如何修改它。基本上,该准则允许人们在此刻随意投票。为了公平起见,我想限制每个成员只投一票 因此,目前,会员使用会员号码登录,然后投票。投票被存储在mysql表中,然后我可以通过查询数据将投票相加 我希望有

我一直在做建立奖项投票系统的工作,我对php和mysql不太了解。但我比这里的任何人都了解这一点,我的老板也在度假。但我一直在重用以前留在我们系统上的代码,并在今年对其进行了调整

基本上,投票系统工作正常,我在mysql中设置了新的表来捕获数据。不过,我在现有代码中发现了一个相当大的缺陷,不知道如何修改它。基本上,该准则允许人们在此刻随意投票。为了公平起见,我想限制每个成员只投一票

因此,目前,会员使用会员号码登录,然后投票。投票被存储在mysql表中,然后我可以通过查询数据将投票相加

我希望有人能帮我添加一两行代码,这将只是检查一个成员是否已经投票。当一个成员投票时,其成员编号与投票选择一起存储在sql表中。因此,最好的方法可能是查看表中是否已经存在Memebrid,如果已经存在,请告诉用户他们已经投票了,或者说已经投票了

<?php
//Insert into volunteer awards
$coach=mysql_real_escape_string($_SESSION['coach']);
$official=mysql_real_escape_string($_SESSION['official']);
$young_volunteer=mysql_real_escape_string($_SESSION['young_volunteer']);
$volunteer=mysql_real_escape_string($_SESSION['volunteer']);

$memberid=$_SESSION['MM_Username'];
$association=$_SESSION['MM_Association'];
$region=$_SESSION['Region'];


$sql_query = mysql_query("INSERT INTO awards_2009_votes (`id`, `member_id`, `region`, `coach`, `official`, `volunteer`, `young_volunteer`) VALUES ('', '$memberid', '$region', '$coach', '$official', '$volunteer', '$young_volunteer')") or die (mysql_error());
?>

这里有一个快速而肮脏的方法:

$sql_query = "SELECT FROM awards_2009_votes WHERE member_id = '$memberid'";
$sql_result = mysql_query($sql_query);
$num_rows = mysql_num_rows($sql_result);

if ($num_rows > 0) {
    // this member has already voted
} else {
    // carry on
}
然而,正如Piskvor所指出的,该解决方案(至少)有两个局限性:

  • 它仅限于包含它的方法,因此它一般不会阻止多次投票——只通过这个特定的方法。(您可以编写一个函数来包含相同的检查,但仍然必须在用户尝试投票的任何地方调用该函数。)
  • 这会对数据库造成额外的压力,这在高流量场景中可能是不可接受的

  • 考虑到这些要点,我的建议是首先运行一个脚本来检查投票表中是否出现重复的member_id值,在每种情况下删除除一个以外的所有值,然后将唯一约束添加到表中。从那里,您可以确保您的表中永远不会有多个具有相同成员id的行。

    您可以向表中添加唯一约束。这是一个一次性操作-您不需要每次运行脚本时都这样做,这是对表结构的更改。在您的MySQL管理工具(例如phpMyAdmin、Navicat、HeidiSQL)中运行此命令:

    更改后,将无法使用相同的成员ID添加第二次投票-插入(或更新)将失败

    这里的优点是,检查是在数据库中自动完成的,因此您不必担心1)使用代码检查重复项,或2)人们手动添加多张投票


    正如@所说,您应该使用
    INSERT IGNORE
    来避免出现“重复键”错误:


    从您的代码中,我不确定您的表结构是什么,但以下表结构将用户投票限制为每个主题一票:

    用户表

    user_id int unsigned not null auto_increment,
    username varchar
    // and other user info fields
    
    topic_id int unsigned not null auto_increment,
    topic_title varchar
    // and other topic info fields
    
    user_id,
    topic_id,
    vote_value,
    primary key (user_id,topic_id) //this is the constraint that will allow only one vote
    
    主题表

    user_id int unsigned not null auto_increment,
    username varchar
    // and other user info fields
    
    topic_id int unsigned not null auto_increment,
    topic_title varchar
    // and other topic info fields
    
    user_id,
    topic_id,
    vote_value,
    primary key (user_id,topic_id) //this is the constraint that will allow only one vote
    
    投票表

    user_id int unsigned not null auto_increment,
    username varchar
    // and other user info fields
    
    topic_id int unsigned not null auto_increment,
    topic_title varchar
    // and other topic info fields
    
    user_id,
    topic_id,
    vote_value,
    primary key (user_id,topic_id) //this is the constraint that will allow only one vote
    

    你可以写几行如下,虽然我没有检查它,但这些应该工作

    $result=mysql_query("select count(*) count from awards_2009_votes where member_id='$memberid'");
    
    $has_voted_array=mysql_fetch_array($result);
    if($has_voted['count']!=0)
    echo "You have already registered youur vote";
    else
    {
    //do normal operation
    $sql_query = mysql_query("INSERT INTO awards_2009_votes (id, member_id, region, coach, official, volunteer, young_volunteer) VALUES ('', '$memberid', '$region', '$coach', '$official', '$volunteer', '$young_volunteer')") or die (mysql_error());
    }
    

    您还需要将选票插入更改为使用INSERT IGNORE以避免生成重复的密钥错误,但这似乎是我认为最好的方法。正如MySQL文档(INSERT IGNORE的第一个Google结果)所述:如果使用IGNORE关键字,则执行INSERT语句时发生的错误将被视为警告。例如,在不忽略的情况下,复制表中现有唯一索引或主键值的行将导致重复键错误,语句将中止。使用IGNORE时,仍不会插入行,但不会发出错误。“插入忽略是一个合理的选择。但是如果你想让你的用户改变他们的投票,你可以考虑替换为插入的工作,除非它替换了重复记录会导致的行。@ DNAGRIL -更好的是,如果你使用MySQL 5。x,你可以使用插入…关于重复密钥更新。我知道这个答案很旧,但它意味着未来的读者要注意SQL注入的工作原理——尽管您正在进行额外的db查询。这可能是问题,也可能不是问题,取决于流量等。此外,此检查只会阻止您的特定脚本添加多个投票。是的,您的解决方案更好。在我看来,snoop123可能只是简单地要求以任何方式获得他想要的功能;我(在我看来)提供了最直接的方法。你的回答中的一个潜在问题是,如果一个成员已经投票不止一次,那么它将不起作用;必须首先进入并删除所有重复的行,然后更新表。(当然,考虑到snoop123的要求,这是无论如何都应该做的事情。)我知道这个答案很旧,但它的意思是让未来的读者注意SQL注入。我知道这个答案很旧,但它的意思是让未来的读者注意SQL注入