Prevent Email Duplicates - php

I have been trying to prevent any user from registering an email that is already registered in the database. I couldn't. Maybe it's because I have to check three tables at the same time. I tried but failed. I hope you are able to help me.
//Check whether Email exists or not
$check="SELECT * FROM admins, engineers, users WHERE admins.Email='$email' OR engineers.Email='$email' OR users.Email='$email'";
$results=mysql_query($check);
//Confirm that the Email doesn't exist
if(mysql_num_rows($results) == 0)
{ $check='true'; }
//Error message to the user that the Email already exists.
else
{
header("location: register.php?email=false");
}
//Register the data
if($check=='true')
{
mysql_query("INSERT INTO admins (Admin, Password, Email, Phone, Date, Time) VALUES ('$username', '$password','$email', '$phone', '$date', '$time')");
header("location: login.php?register=success");
}

Use UNION rather than a cross-product.
SELECT 1 FROM admins WHERE email = '$email'
UNION
SELECT 1 FROM engineers WHERE email = '$email'
UNION
SELECT 1 FROM users WHERE email = '$email'
The cross-product will only work if it finds matches in all the tables, not just one of them.

You can make your life easier by storing all emails in one table. You can use a column named for example 'type' which would then be admin, user or engineer. This makes your lookups much easier instead of having to look through multiple tables.

Related

if the 1.1.2.254 is existing in my database !! use the next 1.1.2.253 proplem

i have an customers i want to add IP address to these customers
i used loop $i=254 to add ip address automatically
but it's give 1.1.2.254 to all the customers how can i fixing it
i need to make loop if the 1.1.2.254 is existing for customer 1 !! use the next 1.1.2.253 for customer 2
$i=254
$res = MySQL_query("INSERT INTO `rm_users`(`username`, `staticipcpe`) VALUES ('$username', '1.1.2.$i');
$i--
use ip unique in db to insert and failure if ip is exiting
now using for($i=254;$i > 0;$i--){ $res = mysql_query("INSERT INTO `rm_users`(`username`, `staticipcpe`) VALUES ('$username', '1.1.2.$i')"); }
and it's working good
The question is a little incomplete and incorrect, but I think you have an IP address from the input or elsewhere. You can search this address with a query.
SELECT EXISTS(SELECT * FROM table1 WHERE ...)
this will return you a true or false value. You can browse the detailed document and similar question
Best way to test if a row exists in a MySQL table
https://dev.mysql.com/doc/refman/8.0/en/exists-and-not-exists-subqueries.html
for($i=254;$i > 0;$i--){
$res = mysql_query("INSERT INTO `rm_users`(`username`, `staticipcpe`) VALUES ('$username', '1.1.2.$i')");
}
this will do the trick!!!. This loop will insert upto 1.1.2.1

mysql auto increment and unique field

I am writing the following command in php:
$query="insert into tableone (user_name, password, name, email) values('$user_name', '$password', '$name', '$email')";
if(mysql_query($query))
{
header("Location:thislocation.php");
} else {
echo '<br><br><font color="red"><strong>Username or EmailId already exists. Please try different Username.<br> If you have forgotten your Password <u><i>click here</i></u>.</strong></font><br>';
}
Here in mysql-db I have made name and email field as unique and id as auto increment, so that no two people have same registration records. The problem is that, if someone uses same username or email, the query fails and else statement is executed. But, it auto-increments the id, without getting records added in db. If someone after that registers successfully, he gets an id not 2 more than the previous one.
How to get auto-incremented just once?
There's no real fix; this is how auto-increment IDs work. IDs are not designed to be "clean", they're designed to fullfill a need to be able to link data together.
It'll be a huge amount of work for your database to keep them in order and (here's the most important part) nobody cares about whether they're aligned anyway. They're numbers without a real-world meaning (by definition of being a database ID) so nothing about them should matter.
The only reason they're "in order" normally is because it's an easy way to generate them.
What you need to do is run an num_rows on it, before you insert it. what num_rows do, it count how many records the SELECT returns, so if it returns 1, there is a place in the database where there are a match, if it returns 0, there are no match
$selectSql = "SELECT * FROM tableone WHERE name= '".$name."' OR email = '".$email."'";
$result = mysql_query($selectSql, $YOUR_DATABASECONNECTION);
$num_rows = mysql_num_rows($result);
if($num_rows){
echo "email or name is already taken";
}else{
$query="insert into tableone (user_name, password, name, email) values('$user_name', '$password', '$name', '$email')";
if(mysql_query($query))
{
header("Location:thislocation.php");
} else {
echo '<br><br><font color="red"><strong>Username or EmailId already exists. Please try different Username.<br> If you have forgotten your Password <u><i>click here</i></u>.</strong></font><br>';
}
}
This is a good way to secure, that the error you're talking about wont happend

Sql statement to prevent duplicates added to the database of a web site

I have created this code in order to register users in my database. What I cannot manage to do, is to prevent adding the same user again and again. Here is my code:
connectDB();
$safe_fullname = mysqli_real_escape_string($mysqli,$_POST['fullname']);
$safe_email = mysqli_real_escape_string($mysqli,$_POST['email']);
$safe_password = mysqli_real_escape_string($mysqli,$_POST['pass']);
$addStatement="Insert into Users (Fullname,Email,Password,Is_Admin) values ('".$safe_fullname."','".$safe_email."','".$safe_password."','N')";
$result = mysqli_query($mysqli,$addStatement) or die(mysqli_error($mysqli));
Add unique to you table for (if it is meant to be unique) email or Username column:
ALTER TABLE Users ADD UNIQUE (Email);
OR
ALTER TABLE Users ADD UNIQUE (Username);
This way database only accepts one record with same email address or Username.
Other way to do this, is to select values from DB with given details. For example, let's use Email column:
$res = mysqli_query($mysqli, "SELECT Email FROM Users WHERE Email = '{$_POST['email']}'");
if(count($res) > 0) {
//exists => do stuff
} else {
//doesn't exist => do stuff
}

what is the wrong with this query?

I have a problem with this query and hope someone will help me to fix this. I am trying to check username and email address are available to register when registering a new user to my site. username is coming from login table and email address is coming from contact table. Now I need to make a query to check given username and email by new users are available to register. If those are not available I want to print error messages. I am trying to make this query something like this but its not working as I expect.
$q = "SELECT username, email FROM login
INNER JOIN contact
WHERE login.username = '$username' OR contact.email = '$email'";
Then I am checking this query in PHP like this
$r = mysqli_query ($dbc, $q);
// Get the number of rows returned:
$rows = mysqli_num_rows($r);
if ($rows == 0) { // No problems!
// register new user
} else { // The email address or username is not available.
if ($rows == 2) { // Both are taken.
$reg_errors['email'] = 'This email address has already been registered.1';
$reg_errors['username'] = 'This username has already been registered.2';
} else { // One or both may be taken.
// Get row:
$row = mysqli_fetch_array($r, MYSQLI_NUM);
if( ($row[0] == $_POST['email']) && ($row[1] == $_POST['username'])) { // Both match.
$reg_errors['email'] = 'This email address has already been registered.3';
$reg_errors['username'] = 'This username has already been registered with this email address.4';
} elseif ($row[0] == $_POST['email']) { // Email match.
$reg_errors['email'] = 'This email address has already been registered.5';
} elseif ($row[1] == $_POST['username']) { // Username match.
$reg_errors['username'] = 'This username has already been registered.6';
}
} // End of $rows == 2 ELSE.
my problem is PHP script always going to this code. query not checking individually username and email. I trying something like this.. username not available and email available, email not available and username available. But always going to this
if ($rows == 2) { // Both are taken.
$reg_errors['email'] = 'This email address has already been registered.1';
$reg_errors['username'] = 'This username has already been registered.2';
}
EDIT: Table structure..
# --------------
# Login Table
# --------------
CREATE TABLE login (
login_id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
username VARCHAR(80) NOT NULL,
password VARBINARY(32) NOT NULL,
PRIMARY KEY (login_id),
UNIQUE(username)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
# --------------
# Contact Table
# --------------
CREATE TABLE contact (
contact_id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
telephone VARCHAR(60) DEFAULT NULL,
mobile CHAR(10) NOT NULL,
email VARCHAR(80) DEFAULT NULL,
PRIMARY KEY (contact_id),
UNIQUE (email)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
You must provide ON clause which define the relationship on how the two tables are related with each other.
SELECT username, email
FROM login
INNER JOIN contact
ON login.colname = b.colName // change to your orignal colName
WHERE login.username = '$username' OR
contact.email = '$email'
As a sidenote, the query is vulnerable with SQL Injection if the value(s) of the variables came from the outside. Please take a look at the article below to learn how to prevent from it. By using PreparedStatements you can get rid of using single quotes around values.
How to prevent SQL injection in PHP?
An alternative way to do this without checking on the value on the tables is by enforcing UNIQUE constraints on column of the table, ex
ALTER TABLE login ADD CONSTRAINT tb_uq UNIQUE (username);
ALTER TABLE contact ADD CONSTRAINT tb_uq1 UNIQUE (email);
when the two alter statements has been successfully executed,you cannot insert value if it already exists on that column.
UPDATE 1
SELECT COUNT(*)
FROM
(
SELECT userName as Value FROM Login
UNION
SELECT email as Value FROM contact
) s
WHERE VALUE IN ('$username','$email')
if the query above will return greater than 0, it means that value(s) already exists.
UPDATE 2
SELECT *
FROM
(
SELECT userName, NULL AS email FROM Login
UNION
SELECT NULL AS username, email FROM contact
) s
WHERE username = '$username' OR email = '$email'
Currently, your query selects every row from both tables as long as there is a single match for one or the other. You can get matching rows from both tables simultaneously:
SELECT username FROM login WHERE username = '$username'
UNION ALL SELECT email FROM contact WHERE email = '$email'
...and also with separate queries.
Your queries are vulnerable to SQL injection.
You are really checking 2 different things. A single query doesn't make sense, at least not a join. I suggest union instead:
select 'username' as exists from login
where username = '$username'
union all
select 'email' as exists from contact
where email = '$email'
This will return a table with a column called exists and a row for each element that exists. Here is what you would get back if both username and email exist:
EXISTS
username
email
Where you run this query, you already know what the username and email they entered are, so there is no point in returning those values from the table.
As others have pointed out, you have a big security hole if $username and $email are being passed in directly from the user. You definitely have to handle that somehow.
Every Inner join clause needs to have a predicate or "ON" condition to specify the rule or rules to be enforced when Joining the two tables...
the query needs an "ON" clause after the Inner Join. I'm not sure what that condition should be, but, as an example....
$q = "SELECT username, email FROM login
INNER JOIN contact
On contact.username = login.userName
WHERE login.username = '$username' OR contact.email = '$email'";
your join have a problem , because you should determine column wich you want join on it!
for example
NNER JOIN contact
On contact.id= login.contactId

Select from table, and insert data to another - Multiply data -SQL

I have a button that will delete all users that fits into this query:
DELETE FROM users WHERE lastlogin < ".time()." - ".$sdata['activitylimit']."*3600
Although, I have to take some parts of each users data, and put it into another table ("username" and "email")
How can I take the users username AND email from the table users, and insert it into my table "reserved_data"?
The table reserved_data looks like this:
id (just the id)
data (the email or username value)
type (what type of data is it((username/email)))
You can't do that directly, thanks to the table layout of the reserved_data table. Why do you do that? Why haven't you got a deleted_users table, containing their username and email? That way you could do this:
$q1 = "INSERT INTO deleted_users (username, email) SELECT username, email FROM users WHERE lastlogin < (".time()." - ".$sdata['activitylimit']." * 3600)";
$q2 = "DELETE FROM users WHERE lastlogin < (".time()." - ".$sdata['activitylimit']." * 3600)";
If you won't change the table, use something like this:
$toDelete = mysql_query("SELECT username, email FROM users WHERE lastlogin < (".time()." - ".$sdata['activitylimit']." * 3600)");
while($user = mysql_fetch_assoc($toDelete))
{
mysql_query("INSERT INTO reserved_data (`data`, `type`) VALUES ('" . $user['username'] . ", 'username'");
mysql_query("INSERT INTO reserved_data (`data`, `type`) VALUES ('" . $user['email'] . ", 'email'");
}
// Now perform the delete
mysql_query("DELETE FROM users WHERE lastlogin < (".time()." - ".$sdata['activitylimit']." * 3600)");
You see the latter requires more code and is generally a bad idea. You lose the relation between a username and its email address.
Besides, you might want to use transactions, since it's possible for one to not be included in the first query but be included in the second query. You then lose this user's data.
And perhaps you can fix all your problems by simply adding an (in)active column to your users table. One rarely wants to really delete data.
Also you can use on delete trigger to log data to reserved_data table. Just move your reserved_data insert to trigger
I would not recommend approach with deletion mark. You don't need it there is no requirement to restore deleted users and it brings quite much new problems.

Categories