I have a Registration Form, but there are a few problems. This is my first registration form. Where the data is needed for data collection needs.
But when someone registers, a lot of duplicate data is in PHPMyAdmin. I've tried various ways, but you know, I'm just a student. I want to prevent duplicate email data.
<?php
$link = mysqli_connect("localhost", "xxxx", "", "db");
// Check connection
if($link === false){
die("ERROR: Could not connect. " . mysqli_connect_error());
}
// Escape user inputs for security
$nama = mysqli_real_escape_string($link, $_REQUEST['nama']);
$nohp = mysqli_real_escape_string($link, $_REQUEST['nohp']);
$email = mysqli_real_escape_string($link, $_REQUEST['email']);
$instagram = mysqli_real_escape_string($link, $_REQUEST['instagram']);
$sql = "INSERT INTO event (nama, nohp, email, instagram) VALUES ('$nama', '$nohp', '$email', '$instagram')";
if(mysqli_query($link, $sql)){
echo "<p class='text-center'>Pendaftaran Berhasil. Akan kembali ke halaman utama dalam 5 detik.<br/>
Atau klik <a href='index.php'>HOME</a></p>";
} else{
echo "ERROR: Could not able to execute $sql. " . mysqli_error($link);
}
// close connection
mysqli_close($link);
?>
What code do I need to add in it, so that someone who has registered their email will not be able to register again?
Sorry for my bad english
Add a unique constraint on the column you wish to be unique, then insert the data without any regard for duplication - MySQL will return an error if the value was duplicate, so all you need to do is catch the error.
First, make the field on that table a unique value (you can not have duplicate values on the table when doing this - if you have duplicate values in the event table, you must fix that first).
ALTER TABLE event
ADD UNIQUE (email);
Then we simply try to insert the data (using a prepared statement instead of escaping), and catch the error - and check for the error-code which belongs to unique constraint errors.
// Enable MySQLi exceptions
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
try {
// Connect to the database
$link = new mysqli("localhost", "xxxx", "", "db");
// Attempt to insert the data
$sql = "INSERT INTO event (nama, nohp, email, instagram) VALUES (?, ?, ?, ?)");
$stmt = $link->prepare($sql);
$stmt->bind_param("ssss", $_REQUEST['nama'], $_REQUEST['nohp'], $_REQUEST['email'], $_REQUEST['instagram']);
$stmt->execute();
$stmt->close();
} catch (Exception $e) {
if ($e->getCode() == 1062) { // 1062 = Unique constraint error code
// Unique field error, handle it
// If you only have unique on the email, example:
// echo 'The email already exists';
} else {
// Handle the error, something else went wrong
error_log($e->getMessage());
echo "An unexpected error occurred";
}
}
You can add a UNIQUE constraint to the email field. This will be done by running the following query:
ALTER TABLE `event` ADD UNIQUE (email);
After that, when you want to insert a new row with an email that already exists in your table, you'll get an error like this: #1062 - Duplicate entry ...
You can catch that exception and react on it in your PHP code like this:
<?php
// perform INSERT query...
if (mysqli_errno($link) == 1062) {
print 'An error occured';
}
Put a unique constraint on email field directly onto table column. This will save you from duplicates (either inserted by your software or in other ways).
After that, you can check explictly via PHP script if the email is already there (but this will cost you an extra query and so is a no-go; moreover as Qirel correctly pointed out, this will expose you to potential concurrency issues) or try to insert and check insertion result (correct and safer way).
You can give emailID unique constraint, whenever the user submits form with a emailID that already exists in the table, MYSQL will throw an exception which you will need to catch and display the error message.
Reference :https://www.w3schools.com/php/php_exception.asp
Related
So I have an HTML form, which is sending data to a database via an "input.php" file which I have connected to my database.
What I wanted to accomplish, is that the data being sent to the database from the HTML form is all numbers. I wanted to know how I can code the input.php file so that when new numbers get submitted from the HTML form, and get sent to a value which already has a number, to add the two up.
For example, Person A fills out a number in the form on day one, per say 5. The next day, he submits the exact same field with the number 3. In the database, instead of overriding the first value, I want to add it up. So on day 1, the database should say "5", but on day 2, it should say "8".
Here is my bare-bones "input.php" file which I will use. The names for the fields will change in my finalized code.
<?php
/* Attempt MySQL server connection. Assuming you are running MySQL
server with default setting (user 'root' with no password) */
$link = mysqli_connect("localhost", "root", "", "demo");
// Check connection
if($link === false){
die("ERROR: Could not connect. " . mysqli_connect_error());
}
// Escape user inputs for security
$first_name = mysqli_real_escape_string($link, $_REQUEST['first_name']);
$last_name = mysqli_real_escape_string($link, $_REQUEST['last_name']);
$email = mysqli_real_escape_string($link, $_REQUEST['email']);
// Attempt insert query execution
$sql = "INSERT INTO persons (first_name, last_name, email) VALUES
('$first_name', '$last_name', '$email')";
if(mysqli_query($link, $sql)){
echo "Records added successfully.";
} else{
echo "ERROR: Could not able to execute $sql. " . mysqli_error($link);
}
// Close connection
mysqli_close($link);
?>
Any help would be appreciated. I thought maybe I could use some javascript validation, however that would be for validating the field, and not adding...so...
Thanks!
Let's say the column name is counts which needs to be summed, and column index id, you could use ON DUPLICATE KEY UPDATE to update based on id if it's already exist, and insert a new row if it's not exist:
UPDATE: You don't need the id field in this situation, as you can automate it using an AUTO_INCREMENT.
// Attempt insert query execution
$sql = "INSERT INTO persons (first_name, last_name, email, counts) VALUES
('$first_name', '$last_name', '$email', '$counts')
ON DUPLICATE KEY UPDATE counts = counts + $counts";
if(mysqli_query($link, $sql)){
echo "Records added successfully.";
} else{
echo "ERROR: Could not able to execute $sql. " . mysqli_error($link);
}
Two things you need to do. First, verify if the record exists or not. Second, If exists update the record by adding the form input to the column . If not exists then insert new record with form input. To update you can write query like
UPDATE TABLE_NAME
SET column_to_update = column_to_update+form_input_number
WHERE email=<email_address> ;
(assuming email is the primary key or replace email with any primary key field name)
I'm making a secret diary website for mysql practice. I've set up 4 columns to accept an id, email, password, and diary entry. The id is the primary key and auto increments whenever I use a query to insert the $_POST['email'] and $_POST['password']. I've successfully been able to add fake entries into the database so that isn't my issue. I'm following a video guide on how to do this and the instructor uses the method mysqli_real_escape_string() with the POST variable inside before inserting into the database and whenever I use it, only blank text is entered into my database. Whenever I don't use that method, my query writes to my db successfully. Can anyone explain why this is?
I've implemented checks prior to the following php code to add to my $error variable if the user doesn't fill in a field or enters incorrect email format.
if (!empty($error)) {
$error = '<p><strong>There were error(s) in your sign-up:</strong></p>'.$error;
} else {
print_r($_POST);
//$emailInput = mysqli_real_escape_string($_POST['email']);
$emailInput = $_POST['email'];
//$passwordInput = mysqli_real_escape_string($_POST['password']);
$passwordInput = $_POST['password'];
$query = "INSERT INTO `users` (`email`, `password`) VALUES ('$emailInput', '$passwordInput')";
if($result = mysqli_query($link, $query)) {
echo "Sign Up Successful";
} else {
$error .= "<p>Could not sign you up - please try again</p>";
}
}
}
I am trying to change a email confirmation function written in sql to PDO. This is the tutorial for your further reference: http://www.phpeasystep.com/phptu/24.html.
This particular section will move the user's information from the temporary table to the permanent table after they click on the verification link sent to their email.
The problem I am having is under this header within that tutorial: STEP4: confirmation.php
My code is similar to that, but I added a few prepared statements as I am trying to prevent SQL injection.
To be clear: I am looking for direction on what else I need to do to switch this from sql to PDO and prevent any sql injection. Examples when providing an answer are crucial as I am a visual learner. Thank you.
Here is my code:
<?php
include('config.php');
//Test DB connection
try {
$conn = new PDO("mysql:host=$Host;db=$svrDb", Username, $Password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(PDOException $e) {
echo 'ERROR: ', $e->getMessage(), "\n";
}
// Passkey that got from link
$passkey=$_GET['passkey'];
$sql1= $conn->prepare("SELECT * FROM temp_members_db WHERE confirm_code ='$passkey'");
$sql_conf1->execute() or die ('Error updating database: '.mysql_error());
$result1=$sql1->fetchall();
// If successfully queried
if($result1){
// Count how many row has this passkey
$count=mysql_num_rows($result1);
// if found this passkey in our database, retrieve data from table "temp_members_db"
if($count==1){
$name=$rows['name'];
$email=$rows['email'];
$password=$rows['password'];
$country=$rows['country'];
// Insert data that retrieves from "temp_members_db" into table "registered_members"
$sql2="INSERT INTO registered_members(name, email, password, country)VALUES('$name', '$email', '$password', '$country')";
$result2=mysql_query($sql2);
}
// if not found passkey, display message "Wrong Confirmation code"
else {
echo "Wrong Confirmation code";
}
// if successfully moved data from table"temp_members_db" to table "registered_members" displays message "Your account has been activated" and don't forget to delete confirmation code from table "temp_members_db"
if($result2){
echo "Your account has been activated";
// Delete information of this user from table "temp_members_db" that has this passkey
$sql3="DELETE FROM temp_members_db WHERE confirm_code = '$passkey'";
$result3=mysql_query($sql3);
}
}
?>
Ok, so you're on the right track but not quite....
The whole reason you use Prepared Statements is so that the database knows what to interpret as SQL, and what not to interpret as SQL. Right now, you have the following:
$sql1= $conn->prepare("SELECT * FROM temp_members_db WHERE confirm_code ='$passkey'");
$sql_conf1->execute() or die ('Error updating database: '.mysql_error());
$result1=$sql1->fetchall();
To take full advantage of PDO and Prepared Statements you should change it to something like this:
$sql1= $conn->prepare("SELECT * FROM temp_members_db WHERE confirm_code = ?");
try{
$sql1->execute(array($passkey));
}catch(PDOException $e){
print "Error!: " . $e->getMessage() . "<br/>";
die();
}
$result1=$sql1->fetchall();
There are a couple reasons for this. In your code, you send the variable $passkey along with your prepare statement, so in essence the prepare operation is useless because $passkey has not been sanitized. Notice in my code I replaced it with a ?. This tells the database:
"Hey, I'm going to be executing a SELECT statement and I'm going to replace the ? with a value from one of my variables, so don't interpret that as SQL!"
Here is a great resource for PDO:
http://wiki.hashphp.org/PDO_Tutorial_for_MySQL_Developers
I'm trying to make my email subscription service reject emails that already exist within my database so users don't subscribe the same email twice. this is what I have but its not working, any ideas?
<?php
if(!isset($_POST['submit']))
exit();
$vars = array('email');
$verified = TRUE;
foreach($vars as $v) {
if(!isset($_POST[$v]) || empty($_POST[$v])) {
$verified = FALSE;
}
}
if(!$verified) {
echo "<p style='color:white; margin-top:25px;'>*Email required*</p>";
exit();
}
$email = $_POST['email'];
if($_POST['submit']) echo "<p style='color:white; margin-top:25px;'>*Check your inbox* </p>";
// Create connection
$con=mysqli_connect("mysql.host","user","password","dbname");
// Check connection
if (mysqli_connect_errno($con))
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
$sql="INSERT INTO emails (email) VALUES ('$_POST[email]')";
if (!mysqli_query($con,$sql))
{
die('Error: ' . mysqli_error($con));
}
$query = mysql_query("SELECT * FROM emails WHERE email='$email'",($con));
if(mysql_num_rows($query) != 1)
{
echo "email already exists";
// redirect back to form and populate with
// data that has already been entered by the user
}
mysqli_close($con);
?>
The easiest way to let MySQL reject the duplicate e-mail address is to make the field unique (http://www.w3schools.com/sql/sql_unique.asp)
ALTER TABLE emails ADD UNIQUE (email)
However, MySQL will not return a warning
Use mysqli_num_rows($query) instead of mysql_num_rows($query)
$query = mysqli_query($con, "SELECT * FROM emails WHERE email='".$email."'");
if(mysqli_num_rows($query) > 0){
echo "email already exists";
}else{
$sql="INSERT INTO emails (email) VALUES ('".$_POST[email]."')";
if (!mysqli_query($con,$sql))
{
die('Error: ' . mysqli_error($con));
}
}
Firstly, you're mixing MySQLi_ with MySQL_ so stick with MySQLi_ and modify the rest of your code accordingly.
This is the logic I use in my scripts, using ? instead of '$email'
$query = $con->query("SELECT * FROM emails WHERE email=?");
// $query = $con->query("SELECT email FROM emails WHERE email=?");
// you may need to use that one --^ if checking a particular column
$numrows=mysqli_num_rows($query);
if($numrows > 0){
die("Email already exists in the database, please try again.");
}
You can use this method, binding parameters. Assuming your column is named email
$query = "SELECT email FROM emails WHERE email=?";
if ($stmt = $con->prepare($query)){
$stmt->bind_param("s", $email);
if($stmt->execute()){
$stmt->store_result();
$email_check= "";
$stmt->bind_result($email_check);
$stmt->fetch();
if ($stmt->num_rows == 1){
echo "That Email already exists.";
exit;
}
}
}
Beside mixing mysql and mysli
Use > not !=
if(mysqli_num_rows($query) > 1)
But this approach means you already have duplicates.
Maybe this will help after you put an unique index on the email column.
As noted in the other answers, you mixed mysqli and mysql functions.
for exemple in both these lines you use mysql instead of mysqli functions.
$query = mysql_query("SELECT * FROM emails WHERE email='$email'",($con));
if(mysql_num_rows($query) != 1)
I also think your code is easily SQL Injectable.
You are using $_POST["email"] in your insert query, without sanitizing it.
Have a look to at least the sql injection wikipedia page
My answer would be as follows,
First, create a UNIQUE KEY of the email column, and then:
INSERT INTO `table` VALUES (/*etc*/) ON DUPLICATE KEY UPDATE /*set a column equal to itself*/
This allows you to attempt inserting into the database, and you can choose whether or not the query throws an error. If you want it to throw an error, then simply do not use ON DUPLICATE KEY, and then catch the SQLException that is thrown from the query and tell the user that the email already exists.
Add a unique constraint to the email column.
Test for error returned on insert or update. I believe the code may be influenced if it is a primary key, foreign key, unique constraint on an index.
With PHP you can use
if( mysql_errno() == X) {
// Duplicate VALUE
} else {
// fail
}
You can test it yourself with a duplicate email or here are the mysql_errNo return values
For non PHP, to determine correct error code test it yourself with a duplicate email or look at the following.
MySQL Errors
I would like to trace the type of error that occurred while executing a query using PDO prepare and execute.
For example, if I had to insert email, Name, DOB, with the email requiring to be unique, instead of writing a special query to check if Email is already taken, I would like to trace the error that occurred and know the same.
You could use a try/catch block around the insert query and handle the double email in the exception handler.
$sql = "INSERT INTO `mystuff` (email, name ) VALUES (:email, :name)";
try {
$sth = $dbh->prepare($sql);
$sth->execute(array(':email' => $email, ':name' => $name));
}
catch (Exception $e) {
echo 'email already taken';
}
Of course you must configure PDO that it throws exceptions on errors.
First of all you will configure your database to put a UNIQUE KEY
ALTER TABLE yourtable ADD CONSTRAINT uniqukey_for_mail UNIQUE(email);
Then you will use PDO with ERRMODE_EXCEPTION
$bddConnect = new PDO('dsn',$user,$password);
$bddConnect->setAttribute(PDO::ATTR_ERRMOD,PDO::ERRMOD_EXCEPTION);
Then when you will update or insert datas, you will just have to wrap your query with a try/catch, and check that your error is a constraint violation
try{
$bddConnect->exec("UPDATE yourtable SET email='already in table EMAIL' WHERE
id='other id than the one that has the email'");
}catch(PDOException $e){
if(strpos('constraint violation',$e->getMessage())!==false){
echo "already taken";
}
}