prevention from duplicated input in a form - php

i have a problem, this is my code and when I add a new input with same name(nazov) it gets in database so it is duplicated. help please
if(isset($_POST['submit']))
{
//get the name and comment entered by user
$nazov = $_POST['nazov'];
//connect to the database
$prip=mysqli_connect("xxx","xxx","xxx","xxx") or die('Error connecting to MySQL server');
//insert results from the form input
$sql = "INSERT IGNORE INTO trieda (nazov) VALUES('$_POST[nazov]')";
$result = mysqli_query($prip, $sql) or die(mysqli_errno($prip) == 1062 ? "Trieda už existuje" : 'Chyba načítavania databázy.');
mysqli_close($prip);
}

you can set the filed you want to be unique in your MYSQL database. So if you try to add the same value you just get error.
You can also do a select first and check if data exists in database before you insert it.
You can do the lazy solution and use REPLACE instead of INSERT. REPLACE updates it, if it exists and insert if not.

Related

How to make a generated code expire after a few times of entering (PHP)?

I have been trying to write a code in PHP that generates a random code, stores it in the database and asks the user to enter it. if the code is entered more than 3 times, the code needs to be expired. this is my code:
<?php
include("ProcessCode.php");
$con = mysqli_connect("localhost","root","") ;
if(mysqli_select_db($con,"login"))
{
echo 'database selected' ;
}
$rand=rand();
echo $rand ;
$sql = "INSERT INTO random (number) VALUES ('$rand') " ;
if(mysqli_query($con,$sql))
{
echo 'inserted' ;
}
?>
$CodeCheck=$_POST['code'];
//Establishing Connection with server
$conn = mysqli_connect("localhost", "root", "");
//Selecting Database
$db = mysqli_select_db($conn, "login");
//sql query to fetch information of registerd user and finds user match.
$query = mysqli_query($conn, "select * from random WHERE number='$CodeCheck'");
$rows = mysqli_num_rows($query);
if (mysqli_num_rows($query) > 0)
{
echo " Code exists already.";
}
if($rows == 1)
{
header("Location: Success.php");
}
else
{
$error = " Code is Invalid";
echo $error;
}
could you please explain how to implement the expiry part?
in your table you could have a field for count. When use login and login is wrong, add + 1 to your count. When user login successfuly, reset the count. If count meet +3, reset the code.
i understand from your question that you need the logic on how to make the random_code expired after inserting from interacted users on your website 3 times ,assuming that , as long as the code is not expired he will be able to do his inserts and you may load it on your page .
i would do that through database queries .
Please follow this instruction listed below
instructions :
while your php page generate the random code , you may store it in database table with a auto reference key , for instance ,
assuming that you have randomly generated a code as below :
"Some random code here"
the above code which was generated by your php page have load it from mysql table called Random_Generated_Code , i would go to edit this table and add new field in it and call it generated_Code_Reference_Key ( could be auto serial number ) to avoid any duplication as well make additional field called Expire_Flag which we are going to use later.
so once your page have loaded the above example code , you should retrieve the generated_Code_Reference_Key along with it and keep it in hidden variable on your page
it should be loaded on the page based on expire_Flag value as a condition
select generated_code from Random_Generated_Code where expire_flag = ""
now once the user try to insert that generated code , in each time he insert it define another table in your database lets call it ( inserted_Codes_by_users) and store in it the username of whoever is doing that on your website as well you have to store the generated_Code_Reference_Key which we are storing in hidden variable as mentioned earlier to indicate which code was used while inserting.
now during page load or any event you want you can find expired code by make select statement from the inserted_Codes_by_users table
select count(generated_Code_Reference_Key) as The_Code_Used_Qty from inserted_Codes_by_users where username = username_of_that_user
so you can get how many times this user have inserted this specific generated_random_Code
retrieve result of the query in a variable and to make sense lets call it The_Code_Used_Qty and make if condition on page load event or any event you like
if The_Code_Used_Qty = 3 then
fire update statement to first table which loaded that random generated code
and update the expire_flag field for that code (Expired) based on reference_key
update Random_Generated_Code set expire_Flag = "expired" where generated_Code_Reference_Key = "generated_Code_Reference_Key" << the one u stored in hidden variable
end if
so now that will get you directly to the point of why we are loading random_generated_code table first time with that condition expire_flag = ""
as it will only retrieve the codes which is not expired .
hopefully this will help you to achieve what you want .
good luck and let me know if you need any help or if you face any confusion while reading my answer.
Good luck .

Get ID from PHP URL and use in a query

I've put certain values like a user id into the url e.g /index.php?id=1 in previous PHP files.
I have a HTML form that has an action like this:
<form name="staffResponse" method="post" action="respond_ticket.php?id=<?php echo $_GET['id']; ?>">
Which when you go to respond_ticket.php and simply echo the value for the id and look at the URL it does it successfully. Whats more the data that I am posting to that file is also done without problem. However I want to then write that information to a table but it does not seem to work.
Here is the respond_ticket.php file
<?php
include 'database/db.php';
$id = $_GET['id'];
$staffResponse = $_POST['staffResponse'];
$sql = "INSERT INTO tickets (staffResponse) VALUES ('$staffResponse') WHERE id='$id'";
$result = mysqli_query($connection, $sql);
if ($result === TRUE) {
echo '<p>Response ' . $staffResponse . ', has been added</p>';
}
else {
echo '<p class="warning">Unable to respond</p>';
}
?>
The db.php file has all the necessary information for connection to the database i.e name password etc. It also opens the question there too.
I keep just getting the warning message that I wrote.
you cant do an insert with a where modifier like this. change it to update ;)
UPDATE tickets SET staffResponse = '$staffResponse' WHERE id = '$id'
You are not supposed to use a WHERE clause with INSERT
$sql = "INSERT INTO tickets (staffResponse) VALUES ('$staffResponse')";
You may wish to set your tickets table up with auto increment so you dont need to insert an id if you haven't done that already.
use ON DUPLICATE UPDATE if it helps
INSERT INTO tickets (id,staffResponse) VALUES ('$id','$staffResponse')
ON DUPLICATE KEY UPDATE id=VALUES(id), staffResponse=VALUES(staffResponse)

PHP/MySQL only updates if the variable is less than a few characters

I've got an update query running so that events in the database can be updated.
For example, the event record table :
Now, when I want to edit the record, I import all the current data from one and show it on a webpage, so that the user can edit the data, as shown:
However, if I submit that page and the event description is more than a few characters long it does not update at all. Here is my PHP/MySQL Code:
$event_title=$_POST['event_title'];
$event_desc=$_POST['event_desc'];
$event_date_start = $_POST['event_date_start'];
$event_date_end = $_POST['event_date_end'];
$db = mysql_select_db("millyaca_events", $connection);
mysql_query("UPDATE events set event_title='$event_title', event_desc='$event_desc', event_date_start='$event_date_start', event_date_end='$event_date_end' where unique_ID='$ID'", $connection);
Only just started learning PHP and MySQL so apologies if it's a really stupid mistake.
Here is the complete submit button script:
if (isset($_POST['submit'])) {
$ID = $_GET['ID'];
$event_title=$_POST['event_title'];
$event_desc=$_POST['event_desc'];
$event_date_start = $_POST['event_date_start'];
$event_date_end = $_POST['event_date_end'];
// Establishing Connection with Server by passing server_name, user_id and password as a parameter
$connection = mysql_connect("localhost", "removed username", "removed password");
// Selecting Database
$db = mysql_select_db("millyaca_events", $connection);
// SQL query to fetch information of registerd users and finds user match.
mysql_query("UPDATE events set event_title='$event_title', event_desc='$event_desc', event_date_start='$event_date_start', event_date_end='$event_date_end' where unique_ID='$ID'", $connection);
mysql_close($connection); // Closing Connection
header("location: https://www.millyacademy.com/admin-zone/events_management/"); // Redirecting To Other Page
}
From the comments we've debugged this to being an apostraphe/quote in the data being passed to the query. To resolve this with your current DB driver use, mysql_real_escape_string, http://php.net/manual/en/function.mysql-real-escape-string.php.
You should switch to MySQLi or PDO though in the future and use prepared statements.
Here's a functional usage (untested, so maybe not functional?) using your current code.
if (isset($_POST['submit'])) {
$ID = (int)$_GET['ID']; //force this to an int, or you could also escape
$event_title= mysql_real_escape_string($_POST['event_title']);
$event_desc= mysql_real_escape_string($_POST['event_desc']);
$event_date_start = mysql_real_escape_string($_POST['event_date_start']);
$event_date_end = mysql_real_escape_string($_POST['event_date_end']);
// Establishing Connection with Server by passing server_name, user_id and password as a parameter
$connection = mysql_connect("localhost", "removed username", "removed password");
// Selecting Database
$db = mysql_select_db("millyaca_events", $connection);
// SQL query to fetch information of registerd users and finds user match.
mysql_query("UPDATE events set event_title='$event_title', event_desc='$event_desc', event_date_start='$event_date_start', event_date_end='$event_date_end' where unique_ID='$ID'", $connection);
mysql_close($connection); // Closing Connection
header("location: https://www.millyacademy.com/admin-zone/events_management/"); // Redirecting To Other Page
}
It is best to never pass user data directly to your queries.
Two Things.
Escape the data provided by user , that will take care of any quotation .
Ensure the db field you are trying to update has enough length.
Also it may be worth skipping the entire POST and do the update using hard coded values to see what is happening.

MySQL/PHP check for duplicate before INSERT

I'm trying to check for an existing entry in MySQL before executing the INSERT statement. If the user enters a name already in the database (field is set to unique) then they should be prompted to re-enter the name.
The problem I'm having is that if the new entry matches a record in any form then the error message displays and no INSERT happens.
For example, if the user enters DUMMY_NEW and there is a record DUMMY_OLD they aren't able to add the record even though DUMMY_NEW does not exist in the table.
I've searched and tried other answers already but can't seem to get this to work.
Code with extraneous bits removed for clarity:
//Create connection to database using mysqli
$conn = new mysqli($dbhost, $dbuser, $dbpass, $db);
//Set variables according to user input on previous form
$Server_Name = $_POST['Server_Name'];
//Check for duplicate server name - if exists inform user else run INSERT ($stmt)
$checkdup = "SELECT * FROM dcr_table WHERE SERVER_NAME = '".$Server_Name."'";
$dupresult = $conn->query($checkdup);
if($dupresult = 1)
{
print "<br>Error! <p></p>";
echo "" . $Server_Name . " already exists in the DCR";
print "<p></p>Please check the Server Name and try again";
}
else {
//Define the INSERT statement
$stmt = "INSERT INTO dcr_master (Server_Name, Description,..., ... , ... )";
//Execute the INSERT statement
$conn->query($stmt);
//Success and return new id
echo "<br><p></p>Record Added!<p></p>";
echo "New id: " . mysqli_insert_id($conn);
//Drop the connection
$conn->close();
};
Edit:
I'm aware of the injection vulnerability. The MySQL account only has SELECT, INSERT and UPDATE rights to the table. The end user must supply the password or submit will fail. This is small app with limited user access at the moment. MySQL escape strings will be implemented after current issue is resolved.
Edit 2:
Using Hobo Sapiens method does work in reporting an existing entry however a new (empty) row is still added to the table. The record ID still auto-increments so what I get is id#300 - record, id#301 - blank, id#302 - record. Is this a result of the IGNORE in the INSERT statement?
Your code creates a race condition if two people attempt to create the same ame at the same time and you're not handling the fallout properly.
If you have set the SERVER_NAME column to UNIQUE then you needn't check for the existence of a server name before you perform your INSERT as MySQL will do that for you. Use INSERT IGNORE ad check the number of affected rows after the query has executed to find out if it worked:
//Create connection to database using mysqli
$conn = new mysqli($dbhost, $dbuser, $dbpass, $db);
//Set variables according to user input on previous form
$Server_Name = $_POST['Server_Name'];
//Define the INSERT statement with IGNORE keyword
$stmt = "INSERT IGNORE INTO dcr_master (Server_Name, Description,..., ... , ... )";
if ($conn->query($stmt) === false) {
die("Database error:".$conn->error);
}
// Check for success
if ($conn->affected_rows == 0) {
print "<br>Error! <p></p>";
echo "" . $Server_Name . " already exists in the DCR";
print "<p></p>Please check the Server Name and try again";
} else {
//Success and return new id
echo "<br><p></p>Record Added!<p></p>";
echo "New id: " . $conn->insert_id;
}
This is an atomic operation so no race condition, and it involves only one call to the database.
I recommend you use either the OOP style or the procedural style for mysqli_*() but don't mix them. Usual warnings about SQL injection apply.
Use mysqli_num_rows
$row_cnt = $dupresult->num_rows;
if ($row_cnt > 0) {
echo "There is a matching record";
}else {
//insert into table
}
This statement:
if($dupresult = 1)
will always return 1. You should first retrieve the first query result (if any), like so:
$row=$dupresult->fetch_array(MYSQLI_NUM);
and then compare the result against NULL:
if(!$row)

How do I check a table to see if a string is already in use?

I am using this code to check my username column (username is primary) in my userdb table to see whether or not the string is already there. If it isn't there then it adds the string entered from a previous form into the username column in my table. But if it is there then it says "(Username) is already in use!".
This works when I put an entry in the username column such as "Sam" and then when I enter Sam into the previous form. But if I have "Sam" in the username column and then enter sam with all lowercase into the previous form, it displays Duplicate entry 'sam' for key 1.
I just want it to say that the string is already in use no matter what kind of casing I enter into the previous form.
$result = mysql_query("SELECT username FROM userdb") or die(mysql_error());
$row = mysql_fetch_array( $result );
$checkuser = $row['username'];
if ( $checkuser == $username ) {
echo "<font color='red'>" .$username. "<font color='black'> is already in use!";
die(mysql_error());
} else {
mysql_query("INSERT INTO userdb (username, password) VALUES('$username', '$password' ) ") or die(mysql_error());;
echo "Data Inserted!";
}
You shouldn't do it this way, because it can lead to race conditions. That's what happens if, between your check and your insert, somebody else inserts that username into the table.
The correct way to do it is to have a primary key on the username and insert the record, catching an exception or error code returned from the DBMS.
If the username is already in there, it won't be inserted again and you'll catch the error.
If it's not there, it will be inserted and you'll get no error.
In terms of your casing problem, I'd either convert all user names to lowercase before insertion or checking, or insert the mixed-case version and lower-case both the DB copy and local copy in all checks.
Change the code to:
strtolower($checkuser) == strtolower($username)
$result = mysql_query("SELECT count(*) FROM userdb where UCASE(username)=UCASE($checkuser);"
Check the number of rows in the result.
Pseudocode:
If num_rows>0
Username exists;
The short answer is:
If you want the usernames to be case-insensitive, you need to store them in the database in a case-insensitive manner. Convert the given username to all lower-case (or all upper-case) first.
$lcusername = strtolower($username);
Then use $lcusername wherever you use $username in the code you supplied.
The long answer is:
You don't need to check for the pre-existence of a key in a table. Assuming you have a PRIMARY KEY attribute on the username field, simply try to your data into the table (after converting it to lower-case). If the database returns a "duplicate key" error, you know the username already existed and you can display the error message. If the database returns that it successfully inserted the row (perhaps by using the mysql_affected_rows function). This saves you from having to do a SELECT before doing the INSERT, greatly simplifying your code.
You should also escape all the strings that you'll be inserting into the table to help avert potential security holes.
$lcusername = strtolower($username);
// Escape strings
$esclcusername = mysql_real_escape_string($lcusername);
$escpassword = mysql_real_escape_string($password);
mysql_query("INSERT INTO userdb (username, password) VALUES('$esclcusername', '$escpassword') ");
if (mysql_affected_rows() == -1) {
// Display error message
} elseif (mysql_affected_rows() == 1) {
// Yay! Insert successful
} else {
// Affected rows is 0. Something went wrong
}
The only way to do this correctly and avoid race conditions* is attempt to insert the user's data and examine any errors to see if the error is a duplicate key error. If you were using PDO (you should be) it would throw an exception which you could catch and examine. I think you can still trap and examine errors using PHP's standard error handling, I'm just not sure how.
*The race condition here is this:
Check user name is unique, it is.
Another user creates an account with that username
You now attempt to create an account with that username for the original user, which causes an error.

Categories