MySQL PHP - Inserting form data into tables. Unknown Error - php

So as the title stated, I'm trying to insert data into 2 tables if the form passes a few conditions (the user is logged in, the user hasn't voted on that product before, all of the fields have been filled in).
It was inserting the data into both tables perfectly when the condition was just:
$sql = "SELECT productid FROM votes WHERE username='$username' LIMIT 1";
But I realized that if the user had voted on any of the products, their username would appear in the table and they would fail the condition without having voted on the product. So I just added:
$sql = "SELECT productid FROM votes WHERE username='$username' AND productid='$id' LIMIT 1";
and now if I try to submit data to the database, it always returns the 'Error inserting into votes table' message but doesn't return the mysql_error() and obviously doesn't insert a new row into the votes table, but strangely it does update the products table.
I just can't figure out what's going on, so if anyone could help me diagnose the problem, I'd really appreciate it! Here's the code:
<?php
if($_SERVER['REQUEST_METHOD'] == 'POST'){
if($_POST['slider_surface'] !== "0" && $_POST['slider_edgewear'] !== "0" && $_POST['slider_centering'] !== "0" && $_POST['slider_corners'] !== "0"){
$dbhost = 'localhost';
$dbuser = 'root';
$dbpass = 'root';
$conn = mysql_connect($dbhost, $dbuser, $dbpass);
if(! $conn )
{
die('Could not connect: ' . mysql_error());
}
$slider_surface = $_POST['slider_surface'];
$slider_edgewear = $_POST['slider_edgewear'];
$slider_centering = $_POST['slider_centering'];
$slider_corners = $_POST['slider_corners'];
$id = preg_replace('#[^a-z0-9]#i', '', $_GET['id']);
session_start();
$username = $_SESSION['username'];
//check if user has already voted
mysql_select_db('products');
$sql = "SELECT productid FROM votes WHERE username='$username' AND productid='$id' LIMIT 1";
$query = mysql_query( $sql, $conn );
$uname_check = mysql_num_rows($query);
if ($username){
if ($uname_check < 1) {
$sql = "INSERT INTO votes ".
"(username,productid,votesurface,voteedgewear,votecentering,votecorners,datetime) ".
"VALUES('$username','$id','$slider_surface','$slider_edgewear','$slider_centering','$slider_corners', now())";
$retval = mysql_query( $sql, $conn );
$id='';
// Make sure the _GET product ID is set, and sanitize it
$id = preg_replace('#[^a-z0-9]#i', '', $_GET['id']);
//Retrieves data from MySQL
$data = mysql_query("SELECT * FROM products WHERE id='$id'") or die(mysql_error());
$product = mysql_fetch_array( $data );
$newvotecount = $product['votecount'] + 1;
$newsum_surface = $product['sumsurface'] + $slider_surface;
$newsum_edgewear = $product['sumedgewear'] + $slider_edgewear;
$newsum_centering = $product['sumcentering'] + $slider_centering;
$newsum_corners = $product['sumcorners'] + $slider_corners;
$sql = "UPDATE products SET votecount='{$newvotecount}', sumsurface='{$newsum_surface}', sumedgewear='{$newsum_edgewear}', sumcentering='{$newsum_centering}', sumcorners='{$newsum_corners}' WHERE id='$id'";
$retval2 = mysql_query( $sql, $conn );
if(! $retval){
die('Error inserting into votes table: ' . mysql_error());
}
else if(! $retval2){
die('Error inserting into products table: ' . mysql_error());
}
$grading_error = 'success';
mysql_close($conn);
} else
$grading_error = 'duplicateuser';
} else
$grading_error = 'nouser';
}
else
$grading_error = 'emptyfields';}
?>

There's a problem when inserting data to table, so there must be an error with the INSERT statement.
As #user2910809 says in previous comments, the sql evaluates as:
INSERT INTO votes (username,
productid,
votesurface,
voteedgewear,
votecentering,
votecorners,
datetime)
VALUES ('magmar',
'52',
'7',
'6',
'5',
'5',
now())
This sentence is syntactically correct. So, if there's an error, it must be with the inserted values.
As #user2910809 states on his comments, there's a UNIQUE key on username column, and it is what was throwing the error.
So the solution is to modify table's indexes to allow multiple rows with the same username.
Edit: as suggested in comments, the SQL to solve this problem was: ALTER TABLE votes DROP INDEX username;

Related

Adding two variables which contain the values from two different tables of same database

Can we add two select sql queries from two different tables of same database and of same data type.These two queries are selecting unique cell from the table after satisfying the where condition. Now i want to sum up these two queries which are of same data type(i.e float type). How to perform addition operation:
For Ex: $sql=1 and $sqlNew=2... i want $add=$sql+$sqlNew=3
$sql = "SELECT num1 FROM tech WHERE name1='dsf'"; //Selecting a particular cell from table tech
$sqlNew = "SELECT num2 FROM technew WHERE name2='asd'"; //Selecting a particular cell from table technew
$add = $sql + $sqlNew; // Can this operation be perfromed?
Want to add cells from two different tables and want to save it in a new variable.
Please let me know how to performe above operation. I am new to sql.
this is my complete code:
<html>
<body>
<?php
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "sample";
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$add="SELECT (tech.num1 + technew.num2) as total FROM tech, technew WHERE tech.name1 = 'def' AND technew.name2 = 'asd'";
$result = mysqli_query($conn, $add);
$row = mysqli_fetch_array($result, MYSQLI_ASSOC);
echo $row['total'];
$sql4 = "INSERT INTO finaladdition (id, finalAddTotal ) VALUES (NULL,'$row[total]')";
$conn->close();
?>
</body>
</html>
You could just do a JOIN (in the example the INNER JOIN is implied) query:
SELECT (a.num1 + b.num2) as total
FROM tech a, technew b
WHERE a.name1 = 'def'
AND b.name2 = 'asd'
Based on further information this is what you should do:
$add="SELECT (tech.num1 + technew.num2) as total FROM tech, technew WHERE tech.name1 = 'def' AND technew.name2 = 'asd'";
$result = mysqli_query($conn, $add);
$row = mysqli_fetch_array($result, MYSQLI_ASSOC);
echo $row['total'];
$sql4 = "INSERT INTO finaladdition (id, finalAddTotal ) VALUES (NULL,$row['total')";

Search a database to update the results

I am taking a users input and storing it in a database, however I want to be able to update the records if a user adds more information. So I want to search the database find the server with the same name and update the the last downtime and the number of downtimes.
$connect = mysqli_connect("localhost", "Username", "Password","Test_downtime");
if (!$connect)
{
die("Connection failed: " . mysqli_connect_error());
}else
{
echo "Connected successfully\n";
}
$servername = $_GET["server_name"];
$downtime = $_GET["downtime"];
$time_now = time();
$result = mysqli_query($connect, "SELECT COUNT(*) FROM `Test_downtime`.`Downtime` WHERE `Server_Name` = '$servername'");
$row = mysqli_fetch_array($result);
// If no downtime have been reported before
if ($row[0] == 0){
$sql = mysqli_query($connect, "INSERT INTO `Test_downtime`.`Downtime` (ID, Server_name, First_downtime, Last_downtime, Num_of_downtime,Total_downtime) VALUES (NULL, '$servername', '$time_now','$time_now',1,'$downtime'); ");
if ($sql==true) {
echo $servername . " has has its first downtime recorded\n";
}
}
//If users is already in the database
else{
$numdowntime = ($row["Num_of_downtime"] + 1);
$id = ($row["ID"]);
$sqlupdate = "UPDATE `Test_downtime`.`Downtime` SET `Num_of_downtime` = $numdowntime, `Last_downtime` = now() WHERE `Server_Name` = '$servername'";
if ($sqlupdate == TRUE) {
echo "Oh No! " . $servername . " has had ". $numdowntime ." of downtimes" ;
}
}
?>
The program works fine if the server is not already in the database, the problems arise if the server is already in the database. I get the message saying it has been updated yet nothing happens to the database. How do i make it so it search and updates the records for the searched item.
So nothing append since you do not execute the sql statement ^^
Take a look here :
$sqlupdate = "UPDATE `Test_downtime`.`Downtime` SET `Num_of_downtime` = $numdowntime, `Last_downtime` = now() WHERE `Server_Name` = '$servername'";
You need to use :
$sql = mysqli_query($connect, $sqlupdate);
Just after it in order to execute it.
Or at least change it to
$sqlupdate = mysqli_query($connect, "UPDATE `Test_downtime`.`Downtime` SET `Num_of_downtime` = $numdowntime, `Last_downtime` = now() WHERE `Server_Name` = '$servername'" );
Btw there is other problem but here is the main one [check out the other answer in order to found another one ]
you are fetching the result as indexed array
mysqli_fetch_array($result);
and here you are accessing results as associative array
$numdowntime = ($row["Num_of_downtime"] + 1);
change your query to
mysqli_fetch_assoc($result);
use
mysqli_num_rows($result);
to checking if you have any data
change
if ($row[0] == 0){}
to
if(mysqli_num_rows($result) ==0){}
A good approach for increasing a count in a column is using SQL to increase that.
$sqlupdate = mysqli_query($connect, "UPDATE `Test_downtime`.`Downtime` SET `Num_of_downtime` = (`Num_of_downtime` + 1), `Last_downtime` = now() WHERE `Server_Name` = '$servername'" );
This way you can skip your $numdowntime calculation, and the result is more accurate.
In your current setup, two users may fire the event at the same time, they both retrieve the same number from the database (ie. 9), both increasing it with one (ie. 10), and writing the same number in the database.
Making your count one short of the actual count.
SQL takes care of this for you by locking rows, and you are left with a more accurate result using less logic :)
You miss the mysqli_query() function, which actually queries the database.
$sqlupdate = mysqli_query("
UPDATE `Test_downtime`.`Downtime`
SET `Num_of_downtime` = $numdowntime, `Last_downtime` = now()
WHERE `Server_Name` = '$servername'"
);

How can i only insert into a database if two inputs doesn't already exist?

I want to give "awards" to users who complete certain tasks such as getting to level 50. I also want to log everything in case something goes wrong and an admin has to manually insert it.
The php for awards is linked on every page and checks if the user from 'users' table has reached level 50. Once the user is level 50 it will insert username, award, time, reason, and who gave the award into a table called 'awards'.
But if the user is level 50 it will continue inserting into the 'awards' table every time the user reload or goes to a new page. How can i only update if the user doesn't already have the specific award?
if(empty($_SESSION['user'])){
}else{
$member_id = htmlentities($_SESSION['user']['id'], ENT_QUOTES, 'UTF-8');
$db_conn = mysqli_connect("localhost", "root", "password", "a276") or die ("Could not connect to database");
$set_award_query = mysqli_query ($db_conn, "SELECT * FROM users WHERE id='$member_id'");
while($row = mysqli_fetch_array($set_award_query, MYSQLI_ASSOC)){
$member_id = htmlentities($_SESSION['user']['id'], ENT_QUOTES, 'UTF-8');
$member_username = htmlentities($_SESSION['user']['username'], ENT_QUOTES, 'UTF-8');
$member_level = $row['level'];
}
//Award level50
if($member_level == '50'){
$award_sql = "INSERT INTO `awards` (`awardusername`, `awardby`, `award`, `awardmessage`) VALUES ('$member_username', 'System', 'level50', 'Congratulations on reaching level 50!')";
$db_conn->query($award_sql);
}else{}
You can create an UNIQUE INDEX over awardusername and award columns:
ALTER TABLE `awards` ADD UNIQUE INDEX awards_key (awardusername, award);
This will prevent second INSERT for the same user and level and will throw 1062 error which you can handle easily I believe.
Create a user_id column in the awards table
Check if the $member_id matches the user_id in the awards table.
Store the user_id($member_id) in the awards table if there is no match.
// Get the user_id from the award table (Example, this code won't work)
$user_id = "SELECT user_id FROM awards WHERE user_id = $member_id";
// Check if they match
if( $member_id !== $user_id ):
// Insert into awards table
endif;
I found a way myself to fix the issue. It might be a stupid way or something (I don't know) but it works
$member_id = htmlentities($_SESSION['user']['id'], ENT_QUOTES, 'UTF-8');
$db_conn = mysqli_connect("localhost", "root", "password", "a276") or die ("Could not connect to database");
$set_award_query = mysqli_query ($db_conn, "SELECT * FROM users WHERE id='$member_id'");
while($row = mysqli_fetch_array($set_award_query, MYSQLI_ASSOC)){
$member_id = htmlentities($_SESSION['user']['id'], ENT_QUOTES, 'UTF-8');
$member_username = htmlentities($_SESSION['user']['username'], ENT_QUOTES, 'UTF-8');
$member_level = $row['level'];
}
$check_award_exist_query = mysqli_query ($db_conn, "SELECT * FROM awards WHERE awardusername='$member_username'");
while($row = mysqli_fetch_array($check_award_exist_query, MYSQLI_ASSOC)){
$award_username = $row['awardusername'];
$selected_award = $row['award'];
}
//Award level50
if($member_username){
if($member_level == '50'){
if($selected_award == 'level50'){
}else{
$award_sql = "INSERT INTO `awards` (`awardusername`, `awardby`, `award`, `awardmessage`) VALUES ('$member_username', 'System', 'level50', 'Congratulations on reaching level 50!')";
$db_conn->query($award_sql);
}
}else{}
}else{}
Thanks to everyone who took their time to try to help me out! :)

Having trouble adding a 24 hour voting system?

There is a script that triggers the code below
I want to disallow executing the script more than once per 24 hours.
I wanted this script to store the last visit time in a table against the user id in a database, then do a time calculation and back them out until the 24 hour expiry time.
Can someone explain how to do this? It would be greatly appreciated if someone could help me with this?
<?php
//Input correct values into this section
$dbhost = '888888';
$dbuser = '888888';
$dbpass = '888888';
$dbname = '888888';
$dbtable = 'redeem';
$dbtable2 = 'playersthatvoted';
//------------------------------------
$input = 'diamond 12';
$player = $_POST['Player'];
$time = time();
if(!isset($_COOKIE['24Hourvote'])){
//---- This is the connection
$conn = mysql_connect ($dbhost, $dbuser, $dbpass) or die ('Error: ' . mysql_error());
mysql_select_db($dbname);
$query1 = "INSERT INTO `".$dbname."`.`".$dbtable."` (`player`, `item`) VALUES ('".$player."', '".$input."')";
$query2 = "INSERT INTO `".$dbname."`.`".$dbtable2."` (`player`, `time`) VALUES ('".$player."', '".$time."')";
mysql_query($query1);
mysql_query($query2);
$query= 'SELECT `player` FROM `playersthatvoted` ASC LIMIT 0, 10 ';
$result = mysql_query($query);
mysql_close($conn);
echo 'Done! Type /redeem in-game to get your diamonds.';
$ip=#$REMOTE_ADDR;
setcookie ("24Hourvote",$ip,time()+86400,'/',true,…
} else {
echo 'You have already voted today! Come back later...'; }
?>
EDIT: and could I make it so that it displays the time left until the user can vote again?
To me it looks like you already know what you have to do:
I wanted this script to store the last visit time in a table
against the user id in a database.Then do a time calculation and
back them out until the 24 hour expiry time.
So:
Forget about the cookie. It is stored on client side and can be manipulated.
Before count the vote check the [lastvisit] field of the current user.
If not set count the vote and set the [lastvisit] field in your table to the current date.
If set calculate the time span between now and the last vote. If bigger than 24 hours, count the vote and set the [lastvisit] field in your table to the current date.
Be aware of:
Manipulated parameters: $_POST['Player'];
SQL injections: VALUES ('".$player."', '".$input."')
If you have problems with one of these tasks then ask about the specific problem.
<?php
//Input correct values into this section
$dbhost = '888888';
$dbuser = '888888';
$dbpass = '888888';
$dbname = '888888';
$dbtable = 'redeem';
$dbtable2 = 'playersthatvoted';
//------------------------------------
$input = 'diamond 12';
$time = time();
if(!isset($_COOKIE['24Hourvote'])){
$ip = $_SERVER['REMOTE_ADDR'];
//---- This is the connection
$conn = mysql_connect ($dbhost, $dbuser, $dbpass) or die ('Error: ' . mysql_error());
mysql_select_db($dbname);
// Escape all user entered data always
$player = mysql_real_escape_string($_POST['Player']);
// Select time for this player if available
$query = "SELECT time FROM playersthatvoted WHERE player = '$player' ORDER BY time DESC LIMIT 0, 1";
$result = mysql_query($query);
if(mysql_num_rows($result) != 0)
{
$row = mysql_fetch_row($result);
$last_visit = $row[0];
$vote_allowed_time = $last_visit + 86400;
// Allowed to vote
if($time > $vote_allowed_time)
{
// Do whatever else you need to here ...
setcookie ("24Hourvote",$ip,time()+86400,'/');
}
else
{
echo 'This player has already voted today! Come back later...';
}
}
else
{
$query1 = "INSERT INTO `".$dbname."`.`".$dbtable."` (`player`, `item`) VALUES ('".$player."', '".$input."')";
$query2 = "INSERT INTO `".$dbname."`.`".$dbtable2."` (`player`, `time`) VALUES ('".$player."', '".$time."')";
mysql_query($query1);
mysql_query($query2);
$query= 'SELECT `player` FROM `playersthatvoted` ASC LIMIT 0, 10 ';
$result = mysql_query($query);
mysql_close($conn);
echo 'Done! Type /redeem in-game to get your diamonds.';
setcookie ("24Hourvote",$ip,time()+86400,'/');
}
} else {
echo 'You have already voted today! Come back later...'; }
?>
Note: Never trust the user input, always validate and escape the data.
Changed:
$player = $_POST['Player'];
to:
$player = mysql_real_escape_string($_POST['Player']);
Added:
// Select time for this player if available
$query = "SELECT time FROM playersthatvoted WHERE player = '$player' ORDER BY time DESC LIMIT 0, 1";
$result = mysql_query($query);
if($result)
{
$row = mysql_fetch_row($result);
$last_visit = $row[0];
$vote_allowed_time = $last_visit + 86400;
// Allowed to vote
if($time > $vote_allowed_time)
{
// Do whatever else you need to here ...
setcookie ("24Hourvote",$ip,time()+86400,'/');
}
else
{
echo 'This player has already voted today! Come back later...';
}
}
else
{
...
}
UPDATE
I would like to highlight the fact that as it stands anyone can enter the player name and try to vote for it and that does not necessarily mean the same user who clicks the vote button.
Additionally the IP address is not being used for any purposes, it may be an idea to use this for further permission/security checks.

How can I optimize or combine these MySQL queries?

I want to check for the username in the users table. If it's found, then I want to get the id. Otherwise, I want to insert the username as a new record, then get the id.
Here's my code:
<?PHP
$sql = "SELECT id FROM users where username = '$username'";
$query = mysql_query($sql) or die(mysql_error());
$result = mysql_num_rows($query);
if($result){
$row = mysql_fetch_array($query);
$userid = $row["id"];
}else{
$sql = "insert into users set username = '$username'";
$query = mysql_query($sql) or die(mysql_error());
$userid = mysql_insert_id();
}
?>
How can I optimize or combine these MySQL queries?
Can I select and insert in the same query?
and would it be better and faster?
If you want this to be fast make sure you index username.
It's better to INSERT first, with the assumption that the username does not exist. If any error is caused by a duplicate conflict, SELECT the existing row.
<?php
$sql = "INSERT INTO users SET username = '"
. mysql_real_escape_string($username) . "'";
$query = mysql_query($sql);
if ($query === true) {
$userid = mysql_insert_id();
} else {
if (mysql_errno() != 1022) { // this is the duplicate key error code
die(mysql_error());
}
$sql = "SELECT id FROM users where username = '"
. mysql_real_escape_string($username) . "'";
$query = mysql_query($sql) or die(mysql_error());
$row = mysql_fetch_array($query);
if ($row !== false) {
$userid = $row["id"];
}
}
?>
The reason this is better is that if you select then insert, someone else might insert the username in the moment between your two SQL statements.
Of course you should have a UNIQUE constraint on users.username.
Re your comment: yes, it should be faster that your script. When there is no duplicate username (which is probably more common), you don't have to run the SELECT.
The best way to optimize an SQL query is not to run it at all.

Categories