Morgan Klaif Morgan Klaif - 1 year ago 48
PHP Question

Adding ranks to mysql database from user input

I am hoping someone can help me with this. I found a post on here allowing a user to type in words in a text box, and being separated by a comma, it added each word separately into a MySQL database. I tried to edit it to match a table I have, but it is not functioning.

Here is the PHP/HTML:

//Connect safely to your database
try {
$db = new PDO("mysql:host=localhost;dbname=DBNAME", 'USER', 'PASSWORD');
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
} catch (PDOException $e) {
die('Cannot connect to mySQL server. Details:'.$e->getMessage());

if ($_SERVER['REQUEST_METHOD']=='POST' && !empty($_POST['words'])) {

$sql = "INSERT INTO rank (id, rank, position) VALUES ('$i', ':word', '$i')";
$stmt = $db->prepare($sql);
$stmt->bindParam(':word', $word);

foreach (explode(',', $_POST['words']) as $word) {
$word = trim($word);
if (empty($word)) {
//Your form
<form method="POST" action="">
<input type="text" name="words"/>
<input type="submit" name="submit" value="Submit"/>

The rank table has id which is an auto increment int(10), rank which is varchar(50), and position which is int(10). The id and position should increase each rank 1, rank 2, rank 3, and so on. Rank 1 would be [1, rank 1, 1], Rank 2 would be [2, rank 2, 2], etc...

I keep getting:

[19-Aug-2016 10:49:14 America/Chicago] PHP Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '1' for key 'PRIMARY'' in /home/wiredtutorial/public_html/ranks.php:26
Stack trace:
#0 /home/wiredtutorial/public_html/ranks.php(26): PDOStatement->execute()
#1 {main}
thrown in /home/wiredtutorial/public_html/ranks.php on line 26

Answer Source

Your error occurs because you are trying to enter an id that already exists. The $i that you put in the query is not a bound parameter like :word. It's a hard-coded value. As a result, increasing it within the loop with $i++ has no effect on the next query.

If your id field is set to auto-increment, don't supply it in the query. The DB will do it for you.

As for the position, it should be bound to a changing parameter as :word is.

$sql = "INSERT INTO rank (rank, position) VALUES (:word, :pos)"
$stmt = $db->prepare($sql);
$stmt->bindParam(':word', $word);
$stmt->bindParam(':pos', $pos);
$pos = 0;

foreach (explode(',', $_POST['words']) as $w){
    $word = trim($w);
    if(empty($word)) continue;