Is is possible to do this with only one sql? - php

I want have an insert query, but before inserting I check whether the username and email are used by someone else. If used, I want to cancel insert query and echo a message to say whether username or email is in use.
Here my code:
$sql = "SELECT 1 FROM user WHERE username='".$_POST['username']."'";
if(!$result = mysql_query($sql))
die(mysql_error());
while($row = mysql_fetch_array($result))
die('This username is already exists');
$sql = "SELECT 2 FROM user WHERE email='".$_POST['email']."'";
if(!$result = mysql_query($sql))
die(mysql_error());
while($row = mysql_fetch_array($result))
die('This email address is already exists');
$sql = "insert into user (username,email,password,tel,type) values ('".$_POST['username']."','".$_POST['email']."','".$_POST['password']."','".$_POST['telnumber']."','member')";
if(!mysql_query($sql))
die(mysql_error());
I want these three sql statements in one. It can be either using cases or something else that you suggest. So,
Is it possible to zip this code into one sql query?
As a result what I need is
sql = "sql_query"
if(!$result = mysql_query($sql))
die(mysql_error());
while($row = mysql_fetch_array($result)){
if($row['result']==1)
die('This username is already exists');
else if($row['result']==2)
die('This email is already exists');
}
die('you have succesfully registered');
thanks for any advice.

While I suggest you follow #cularis' answer, you may be interested in the following alternative:
Give email and username the UNIQUE constraint, by creating a unique index for both of these.
run your INSERT query, and if this fails... (due to duplicate keys)
run the suggested combined SELECT, to determine which field existed (username or email)

You can combine the first two queries like this:
$sql = "SELECT * FROM user WHERE username='".$_POST['username']."' OR email='".$_POST['email']."'";
Have look at mysql_real_escape string to sanatize your input.

Assuming you don't care about a more specific error case you could probably just do the following:
$sql = "SELECT * FROM user WHERE username='".$_POST['username']."' OR email='".$_POST['email']."'";
if(!$result = mysql_query($sql))
die(mysql_error());
while($row = mysql_fetch_array($result))
die('The username or email address is already being used');
$sql = "insert into user (username,email,password,tel,type) values ('".$_POST['username']."','".$_POST['email']."','".$_POST['password']."','".$_POST['telnumber']."','member')";
if(!mysql_query($sql))
die(mysql_error());
This isn't the best of designs if you're looking for, as I said, specific error cases. So if you are okay with just telling the person there is an error that one or both are in use then that should work.
I am not sure as I am very rusty in PHP/MySQL but I assume that if such cases of both exist then multiple rows may be returned and I forget exactly how mysql_fetch_array works but I assume it's an array of all results valid for the query so you should be set. As long as the array exists, you know there was a hit in the db.

Related

Inserting data into Mysql with PHP while loop

I'm trying to check an email against my database, and if it doesn't already exist, add it to the database.
$query = "SELECT * FROM users";
$inputQuery = "INSERT INTO users (`email`,
`password`) VALUES ('$emailInput',
'$passInput')";
$emailInput = ($_POST['email']);
$passInput = ($_POST['password']);
if ($result = mysqli_query($link, $query)) {
while ($row = mysqli_fetch_array($result)) {
if ($row['email'] == $emailInput) {
echo "We already have that email!";
} else {
mysqli_query($link, $inputQuery);
echo "Hopefully that's been added to the database!";
}
}
};
It can detect an existing email, it's just the adding bit...
Currently this seems to add a new empty row for each existing row (doubling the size).
I'm trying to understand why it doesn't add the information, and how to escape the loop somehow.
Also for good measure, everyone seems to reuse $query, but this seems odd to me. Is it good practice to individually name queries as I have here?
Please let me know if there's anything else I should add.
I am not going to talk about the standards but straight, simple answer to your question.
Approach - 1:
INSERT INTO users (`email`,`password`) SELECT '$emailInput', '$passInput' from DUAL WHERE NOT EXISTS (select * from users where `email` = '$emailInput');
Approach - 2:
- Create a unique key on email column
- use INSERT IGNORE option.
user3783243 comments are worth noting
Try this :
$emailInput = mysqli_real_escape_string($link, $_POST['email']);
$passInput = mysqli_real_escape_string($link, $_POST['password']);
$qry3=mysqli_query($link,"select * from users where `email`='".$emailInput."'");
$num=mysqli_num_rows($qry3);
if($num==1) {
echo "Email-Id already exists";
} else {
$inputQuery = mysqli_query($link,"INSERT INTO users (`email`, `password`) VALUES ('".$emailInput."', '".$passInput."')");
if ($inputQuery) {
echo "Hopefully that's been added to the database!";
}
}
Your code seems to be a bit over-engineered because why not to pass you $_POST['email'] to select query where clause
"SELECT * FROM users where email = $emailInput" and then check if it is there already.
Also, keep in mind that this is an example only, and you should always check and sanitize user input.
From another hand you can do it with MySQL only using INSERT ... ON DUPLICATE KEY UPDATE Syntax. https://dev.mysql.com/doc/refman/8.0/en/insert-on-duplicate.html
That requires to add unique key for email column.

PHP & MySQL Search Column for value

I am a little confused about how $query works and how I can find a value... Say I have a checkuser.php script. The purpose here is to echo "Correct" if the user already exists. I have the columns (username, password, email). What I want to know is how can I search the column username for value $username? This is what I have currently:
$query = sprintf("SELECT * FROM users WHERE CONCAT(username) LIKE '$u'");
$result = mysql_query($query);
if(mysql_num_rows($result) != 1)
echo "Username Not Found";
Thanks!
This should work. However, I didn't test it:
$query = "SELECT * FROM users WHERE username = '$u'";
$result = mysql_query($query);
if(mysql_num_rows($result) > 0)
echo "Username Not Found";
In your query, you do not need to use the sprintf() function at all. an SQL query is inserted as a regular string.
Furthermore you don't need to use CONCAT() SQL function either.
Then if you want to check against an exact string you can just compare with the = operator instead of using SQL LIKE statement.
I haven't tested it, but this should work:
$q=mysql_query("select ysername from user where username='$u'");
$count=mysql_num_rows($q);
If ($count>0) { echo "usename fount";};

Registration constraint for duplicate users in a web site

I have created the following sql statement in order to check if a user already exists in the database and if so to prevent his registration. However, I have done something wrong because now every registration even from not duplicate users is denied.
$res = mysqli_query($mysqli, "SELECT * FROM Users WHERE Email = '{$_POST['email']}' OR Fullname = '{$_POST['fullname']}'");
if (count($res) > 0) {
echo "<script type=\"text/javascript\">window.alert('User already exists!');window.location.href = '/Register.php';</script>";
exit;
}
If you want to prevent duplicate users, then use constraints or unique indexes (really the same thing):
create unique index users_email on users(email);
create unique index users_fullname on users(fullname);
This will prevent duplicates from going into these fields at the database level. Much safer than trying to do this at the application level.
As you can read in the manual, mysqli_query()
will return a mysqli_result object.
You can use mysqli_num_rows() to properly do this:
$result = mysqli_query($mysqli, "SELECT * FROM Users WHERE Email = '{$_POST['email']}' OR Fullname = '{$_POST['fullname']}'");
$row_count = mysqli_num_rows($result);
if ($row_count > 0) {
//etc.
}

Check if an user is in a database

I have developed a game with Javascript and when the user finishes it, I must save his record in a database. Here you see the code:
$temp = $_POST['playername']; //username
$text = file_get_contents('names.txt'); //list with all usernames
//this text file contains the names of the players that sent a record.
$con=mysqli_connect("localhost","username","pass","my_mk7vrlist");
if (stripos(strtolower($text), strtolower($temp)) !== false) {
//if the username is in the list, don't create a new record but edit the correct one
mysqli_query($con, "UPDATE `my_mk7vrlist`.`mk7game` SET `record` = '".$_POST['dadate']."' WHERE `mk7game`.`playername` = ".$temp." LIMIT 1 ");
} else {
//The username is not in the list, so this is a new user --> add him in the database
mysqli_query($con, "INSERT INTO `mk7game` (`playername`,`record`,`country`,`timen`) VALUES ('".$_POST['playername']."', '".$_POST['dadate']."', '".$_POST['country']."', '".$_POST['time_e']."')");
file_put_contents("names.txt",$text."\n".$temp);
//update the list with this new name
}
//Close connection
mysqli_close($con);
When I have a new user (the part inside my "else") the code works correctly because I have a new row in my database.
When the username already exists in the list, it means that this player has already sent his record and so I must update the table. By the way I cannot edit the record on the player that has alredy sent the record.
mysqli_query($con, "UPDATE `my_mk7vrlist`.`mk7game` SET `record` = '".$_POST['dadate']."' WHERE `mk7game`.`playername` = ".$temp." LIMIT 1 ");
It looks like this is wrong, and I can't get why. I am pretty new with PHP and MySQL.
Do you have any suggestion?
You're missing quotes around $temp in the UPDATE statement:
mysqli_query($con, "UPDATE `my_mk7vrlist`.`mk7game`
SET `record` = '".$_POST['dadate']."'
WHERE `mk7game`.`playername` = '".$temp."'
^ ^
LIMIT 1 ") or die(mysqli_error($con));
However, it would be better to make use of prepared statements with parameters, rather than inserting strings into the query.
Escape your user input!
$temp = mysqli_real_escape_string($con, $_POST['playername']);
Make sure to stick your mysqli_connect() above that
$select = mysqli_query($con, "SELECT `id` FROM `mk7game` WHERE `playername` = '".$temp."'");
if(mysqli_num_rows($select))
exit("A player with that name already exists");
Whack that in before the UPDATE query, and you should be good to go - obviously, you'll need to edit it to match your table setup

Checking if row exists under criteria (PDO, prepare???)

The code below indicates my attempts to try and find out whether a row exists with the criteria gave in the code. It defaults to the else statement, correctly, but doesn't work with the 'if' statement if the if statement appears to be true (there are no emails down as ashfjks#sdhja.com), and instead the code proceeds. The latter part of this code is mostly to expand on the situation. the row can only exist or not exist so I don't understand why it's not strictly doing one or the other. I am converting into PDO for site secuirty, thats why not all is in PDO, yet. I am sorry if this question is too localised?
$stmt = $pdo->prepare("SELECT * FROM table WHERE email = ?");
$stmt->execute(array("$email"));
$row3 = $stmt->fetch(PDO::FETCH_ASSOC);
while($row = $stmt->fetch()) {
if ( ! $row3) {
// Row3 doesn't exist -- this means no one in the database has this email, allow the person to join
$query = "INSERT INTO table (username, email, password, join_date) VALUES ('$username', '$email', SHA('$password1'), NOW())";
mysqli_query($dbc, $query);
$query = "SELECT * FROM table WHERE username = '$username'";
$data2 = mysqli_query($dbc, $query);
while ($row = mysqli_fetch_array($data2)) {
$recipent = '' . $row['user_id'] . '';
$query = "INSERT INTO messages (recipent, MsgTit, MsgR, MsgA, sender, time, readb, reada, MsgCon) VALUES ('$recipent', '$MsgTit', '$MsgR', '$MsgA', '$sender', NOW(), '$readb', '$reada', '$MsgCon')";
mysqli_query($dbc, $query);
// Aftermath.
echo '<p>Your new account has been successfully created. You\'re now ready to log in. After this you should implement basic character-details on your users profile to begin the game.</p>';
mysqli_close($dbc);
exit();
} }
else {
// An account already exists for this email, so display an error message
echo '<p class="error">An account already exists for this e-mail.</p>';
$email = "";
}
}
Your if statement will never be executed. You need to check the number of rows returned. This is what you want:
Note: I originally used $stmt->rowCount(), but the OP said that didn't work for him. But I'm pretty sure the cause of that error was coming from somewhere else.
if (!($stmt = $pdo->prepare("SELECT * FROM table WHERE email = ?"))) {
//error
}
if (!$stmt->execute(array("$email"))) {
//error
}
//The $row3 var you had was useless. Deleted that.
$count = 0;
while ($row = $stmt->fetch()) {
$count++;
}
//The query returned 0 rows, so you know the email doesn't exist in the DB
if ($count== 0) {
$query = "INSERT INTO table (username, email, password, join_date) VALUES ('$username', '$email', SHA('$password1'), NOW())";
if (!mysqli_query($dbc, $query)) {
//error
}
$query = "SELECT * FROM table WHERE username = '$username'";
if (!($data2 = mysqli_query($dbc, $query))) {
//error
}
while ($row = mysqli_fetch_array($data2)) {
$recipent = '' . $row['user_id'] . '';
$query = "INSERT INTO messages (recipent, MsgTit, MsgR, MsgA, sender, time, readb, reada, MsgCon) VALUES ('$recipent', '$MsgTit', '$MsgR', '$MsgA', '$sender', NOW(), '$readb', '$reada', '$MsgCon')";
if (!mysqli_query($dbc, $query)) {
//error
}
// Aftermath.
echo '<p>Your new account has been successfully created. You\'re now ready to log in. After this you should implement basic character-details on your users profile to begin the game.</p>';
mysqli_close($dbc);
exit();
}
}
//The query did not return 0 rows, so it does exist in the DB
else {
// An account already exists for this email, so display an error message
echo '<p class="error">An account already exists for this e-mail.</p>';
$email = "";
}
And you should totally convert the rest of those queries to use PDO.
+1 to answer from #Geoff_Montee, but here are a few more tips:
Make sure you check for errors after every prepare() or execute(). Report the error (but don't expose your SQL to the user), and fail gracefully.
Note that even though you checked for existence of a row matching $email, such a row could be created in the brief moment of time since your check and before you INSERT. This is a race condition. Even if you SELECT for a row matching $email, you should also use a UNIQUE constraint in the database, and catch errors when you execute the INSERT in case the UNIQUE constraint blocks the insert due to conflict.
SELECT email instead of SELECT *. If you have an index on email, then the query runs more efficiently because it can just check the index for the given value, instead of having to read all the columns of the table when you don't need them. This optimization is called an index-only query.
Likewise use SELECT user_id instead of SELECT *. Use SELECT * only when you really need to fetch all the columns.
Bcrypt is more secure than SHA for hashing passwords.

Categories