2016-12-31 47 views
0

我一直在爲一個論壇寫一些代碼,並且是PHP新手,但我遇到了一些麻煩。 當我通過輸入答案測試程序時,我收到一個顯示「ERROR」的網頁。論壇響應錯誤:重複項PRIMARY鍵

改變echo "ERROR"echo mysql_error()後,網頁改成這樣:

Notice: Undefined index: id in C:\xampp5\htdocs\add_answer.php on line 14

Notice: Undefined index: a_name in C:\xampp5\htdocs\add_answer.php on line 30

Notice: Undefined index: a_email in C:\xampp5\htdocs\add_answer.php on line 31

Notice: Undefined index: a_answer in C:\xampp5\htdocs\add_answer.php on line 32 Duplicate entry '1' for key 'PRIMARY'

<?php 

$host="localhost"; // Host name 
$username=""; // Mysql username 
$password=""; // Mysql password 
$db_name="test"; // Database name 
$tbl_name="forum_answer"; // 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"); 

// Get value of id that sent from hidden field 
$id = $_POST['id']; 

// Find highest answer number. 
$sql="SELECT MAX(a_id) AS Maxa_id FROM $tbl_name WHERE question_id='$id'"; 
$result=mysql_query($sql); 
$rows=mysql_fetch_array($result); 

// add + 1 to highest answer number and keep it in variable name "$Max_id". if there no answer yet set it = 1 
if ($rows) { 
    $Max_id = $rows['Maxa_id']+1; 
} 
else { 
    $Max_id = 1; 
} 

// get values that sent from form 
$a_name = $_POST['a_name']; 
$a_email = $_POST['a_email']; 
$a_answer = $_POST['a_answer']; 

$datetime=date("d/m/y H:i:s"); // create date and time 

// Insert answer 
$sql2="INSERT INTO $tbl_name(question_id, a_id, a_name, a_email, a_answer, a_datetime)VALUES('$id', '$Max_id', '$a_name', '$a_email', '$a_answer', '$datetime')"; 
$result2=mysql_query($sql2); 

if($result2){ 
    echo "Successful<BR>"; 
    echo "<a href='view_topic.php?id=".$id."'>View your answer</a>"; 

    // If added new answer, add value +1 in reply column 
    $tbl_name2="forum_question"; 
    $sql3="UPDATE $tbl_name2 SET reply='$Max_id' WHERE id='$id'"; 
    $result3=mysql_query($sql3); 
} 
else { 
    echo "ERROR"; 
} 

// Close connection 
mysql_close 

(); 
?> 

對於我不關心安全的那一刻,我打算以後在軌道下解決安全問題。

+1

**警告**:如果您只是學習PHP,請不要使用['mysql_query'](http://php.net/manual/en/function.mysql-query.php)接口。這是非常可怕和危險的,它在PHP 7中被刪除了。[PDO的替代品並不難學](http://net.tutsplus.com/tutorials/php/why-you-should-be-using-phps -pdo-for-database-access /)以及[PHP The Right Way](http://www.phptherightway.com/)等指南介紹了最佳實踐。你的用戶數據是**不是** [正確轉義](http://bobby-tables.com/php.html),並有[SQL注入漏洞](http://bobby-tables.com/),並且可以被利用。 – tadman

+0

打印出正確的錯誤信息而不是無用的錯誤。 – Shadow

+0

用'echo mysql_error()'替換'echo「ERROR」'並將結果編輯到您的問題中。 –

回答

0

您的代碼中存在競爭條件。當多個用戶同時擊中數據庫時,他們最終讀取相同的$Max_id並隨後嘗試插入相同的$Max_id + 1。例如:

  1. 用戶1選擇ID 42
  2. 用戶2選擇ID 42
  3. 用戶1個插入ID 43
  4. 用戶2個插入ID 43

需要聲明主與AUTO_INCREMENT屬性的關鍵列(或者簡單地聲明它爲SERIAL)。這樣,當您插入新行時,數據庫引擎將自動更新該ID並保證唯一值。