2013-04-14 129 views
0

我是PHP/MySQL和整個網站設計的新手。我正在建立一個預定義用戶可以投票的網站。我有一個包含用戶列表的數據庫。我正在努力避免重複投票。我讀過你可以阻止IP地址或使用cookie,但我試圖使用另一種方法。避免重複投票

在我的數據庫名爲'用戶'我有三列 - 用戶名,密碼和標誌。 標誌的默認值爲0.一旦用戶投票,我將該特定用戶的標誌設置爲1.現在,如果用戶試圖再次投票,我想檢查數據庫中標誌的值。如果它是0,我會將他發送給「感謝您投票」頁面,並更新我創建的另一個數據庫,稱爲結果,以記錄每個候選人收到的投票數。如果不是,我帶他到另一頁說:「你已經投了票。」到目前爲止,一切正常,除非我不知道如何讀取數據庫中的標誌值並使用它的if條件。

這是我到目前爲止有:

<?php 

$host="localhost"; // Host name 
$username="dbxxxxx"; // Mysql username 
$password="password"; // Mysql password 
$db_name="dbxxxxx_users"; // Database name 
$tbl_name="users"; // Table name 


// Connect to server and select databse. 
mysql_connect("$host", "$username", "$password")or die("cannot connect"); 
mysql_select_db("$db_name")or die("cannot select DB"); 

$user = $_COOKIE["details"]; //cookie details has the username the user used to log in 

$SQL = "SELECT flag FROM users WHERE Username='$user'"; 
$flag = mysql_query($SQL); //no clue what's happening here. Just trying random stuff 
$db_field = mysql_fetch_assoc($flag); 


if($db_field==0)  //checking the value of flag in the database 
{  
    mysql_query("UPDATE result SET Votes=Votes+1 //if flag in database = 0 
    WHERE Name='Candidate1'"); //updates result for candidate1 if the user voted for 1 

    $user = $_COOKIE["details"]; //reading the cookie again. can be omitted. 

    mysql_query("UPDATE users SET flag=1 //changing flag to 1 so user cannot vote again 
    WHERE Username='$user'"); 

    header("location: http://www.lithuaniavote.com/thankyou.html"); 
} 

else //flag != 1 or user has already voted 
{ 
    header("location: http://www.lithuaniavote.com/alreadyvoted.html"); 
} 

?> 

PS:此代碼更改爲0的標誌1在數據庫中。但是,if條件有問題。即使標誌爲1,我也能夠投票,這表明我已經投了票,換句話說,它從未將我帶到已投票頁面。

+1

我會猜測問題是你的SQL更新標誌的語法錯誤,但是你的代碼有比這更糟糕的問題。您正在使用未轉義的用戶輸入構建SQL查詢。 – Cairnarvon

+0

調試你的代碼:[如何在PHP中獲取有用的錯誤消息?](http://stackoverflow.com/q/845021/1409082) – Jocelyn

+1

你也在混合'$ db_field'和'$ fdb_field'。 – icktoofay

回答

0

原始代碼:

$SQL = "SELECT flag FROM users WHERE Username=$user"; 
$flag = mysql_query($SQL); //no clue what's happening here. Just trying random stuff 
$db_field = mysql_fetch_assoc($flag); 
if($db_field==0)  //checking the value of flag in the database 

試試這個:

$SQL = "SELECT flag FROM users WHERE Username = '$user'"; // $user should be in 'quotes' 
$flag = mysql_query($SQL); // This is the actual query to the database 
$db_field = mysql_result($flag, 0); // This is the result of the query. 
if($db_field===0) // Use 3 equals signs instead of 2 in this case (which means "exactly equal to") 
+0

這並沒有多大幫助。如果我用這裏的代碼替換代碼......即使用戶第一次投票,每次都會將我帶到已投票頁面。 讓我問你這個問題,你如何從數據庫中讀取一個值並將其存入另一個變量?如果您要從數據庫中讀取值並將其存儲在PHP中的變量中,那麼您會如何做到這一點? –

+0

非常感謝。感謝您的反饋。:) –

0

我想你應該嘗試一個更清潔(和前瞻性)的方法。讓我重新構建解決問題的方法與PDO:

namespace Voting { 
    $pdo = new \PDO("mysql:host={$host};dbname={$db_name};charset=utf8", $username, $password); 

    if ($query1 = $pdo->prepare("SELECT `flag` FROM `users` WHERE `Username` = ?;", [\PDO::ATTR_CURSOR => \PDO::CURSOR_FWDONLY])) { 
     if ($query1->execute([$_COOKIE["details"]])) { 
      $result = $query1->fetch(\PDO::FETCH_ASSOC); 

      if (intval($result["flag"]) === 0) { 
       if ($query2 = $pdo->prepare("UPDATE `users` SET `flag` = '1' WHERE `Username` = ?")) { 
        $query2->execute([$_COOKIE["details"]]); 
        $pdo = null; 
        header("Location: http://www.lithuaniavote.com/thankyou.html"); 
       } 
      } else { 
       $pdo = null; 
       header("Location: http://www.lithuaniavote.com/alreadyvoted.html"); 
      } 
     } 
    } 
} 

警告:考慮到我沒有檢查$_COOKIE安全。您必須進行某種形式的衛生處理以防止注射和其他漏洞。

+0

哦,幾乎忘了提及它...這個代碼應該按原樣在PHP 5.4.x下運行。如果你需要在PHP 5.3.x中運行,用數組括號('[]')替換數組,並用'array()'替換它們。如果是PHP 5.2.x,請刪除所有PDO操作的名稱空間和'\\'符號(它只能在PHP 5.3.x +中使用)。希望有幫助;) –

+0

非常感謝您的回覆,Julio。我使用PHP 5.3.15版本,它顯示我在這一行上有錯誤:if($ query1 = $ pdo-> prepare(「SELECT'flag' FROM'users' WHERE'Username' =?;」,[\ PDO :: ATTR_CURSOR => \ PDO :: CURSOR_FWDONLY])) 以下是錯誤: 解析錯誤:語法錯誤,意外的'['in /nfs/c03/h04/mnt/166547/domains/lithuaniavote.com/html/在線8投票。希望你能進一步幫助。 –

+0

當然,我習慣於編寫符合PHP 5.4的代碼,所以你只需要用'array(\ PDO :: ATTR_CURSOR => \ PDO:'替換'[\ PDO :: ATTR_CURSOR => \ PDO :: CURSOR_FWDONLY] :CURSOR_FWDONLY)'。這應該讓你去:) –