Select two different columns from the same row using two different queries - php

I want to run two queries at a time in a function to verify the username and email separately when registering. If one of them already exists in the database, it will return the correct error message on the form.
I investigate them separately so that they can be linked to two separate messages based on a query.
If the username already exists in the database, display the corresponding message. If I put them in a single query, then the separate investigation cannot be done.
My error is: It does not allow you to run two queries at the same time and throws the following error: there is a problem with the preceding parameter. Or it returns an incorrect value.
function pl($connection) {
$query = "SELECT username FROM users WHERE username = ?";
$query2 = "SELECT email FROM users WHERE email = ?";
if ($statment = mysqli_prepare($connection, $query) && $statment2 = mysqli_prepare($connection, $query2)) {
mysqli_stmt_bind_param($statment, "s", $_POST['usern']);
mysqli_stmt_execute($statment);
$result = mysqli_stmt_get_result($statment);
$record = mysqli_fetch_assoc($result);
mysqli_stmt_bind_param($statment2, "s", $_POST['email']);
mysqli_stmt_execute($statment2);
$result2 = mysqli_stmt_get_result($statment2);
$record2 = mysqli_fetch_assoc($result2);
}
if ($result != null) {
echo "succes";
//it will enter even if there is an error
}
}
How it could be solved to execute two mysqli_prepare() at a time?

Why you do not use one query?
Something like:
$query = "SELECT username, email FROM users WHERE username = ? and email = ?";
$statment = mysqli_prepare($connection, $query);
mysqli_stmt_bind_param($statment, "ss", $_POST['usern'], $_POST['email']);
mysqli_stmt_execute($statment);
$result = mysqli_stmt_get_result($statment);
$record = mysqli_fetch_assoc($result);
if (!$record) {
echo "succes";
//it will enter even if there is an error
}
also you miss the } at end of your first if

Related

MySQLi Prepared statement query won't run

I was trying to make an API of post method that and take one value from the database from my post method.
<?php
if($_SERVER['REQUEST_METHOD']=='POST') {
$response = array();
//get data
$username = $_POST['username'];
$password = $_POST['password'];
$key_check = $_POST['key_check'];
require_once('Connection.php');
$check_key = "SELECT key_check FROM testing1 WHERE username =? AND password =?";
$insert_key= "UPDATE testing1 SET key_check =? WHERE username =? AND password = ?";
// $insert_key = "INSERT INTO MyGuests (username, password, key_check) VALUES (?, ?, ?)"
if ($result_p = mysqli_prepare($connection,$check_key)){
mysqli_stmt_bind_param($result_p,"ss",$username,$password);
mysqli_stmt_execute($result_p);
$row = $result_p ->get_result();
while ($row1 = $row -> fetch_assoc()){
if(isset($row1["key_check"])){
if($result_p2 = mysqli_prepare($connection,$insert_key)){
mysqli_stmt_bind_param($result_p2,"sss",$username,$password,$key_check);
mysqli_stmt_execute($result_p2);
mysqli_stmt_close($result_p2);
}
}else{
//do something
}
}
}
else{
//do something
}'''
As you can see in the code above, The code will take the key_check value from the first query and then then based on the result if it's null or not, the program will run the second query to add the data from the from the post method. I already checked that the value is null but for some reason the second query did not want to run, is there any thing that I could do or does my logic is wrong in the first place?

How come my script can't check the database for similar usernames? [duplicate]

This question already has answers here:
How to check if a row exists in MySQL? (i.e. check if username or email exists in MySQL)
(4 answers)
Closed 3 years ago.
I'm trying to check the database for a taken username when the user signs up. The connection to the database works fine as a similar password will be added to the table.
$username = $_POST['user'];
$password = $_POST['password'];
$hash = password_hash($password, PASSWORD_DEFAULT);
$s = 'SELECT * FROM users WHERE username = "$username"';
$result = mysqli_query($con, $s);
$num = mysqli_num_rows($result);
if ($num == 1) {
echo "Username is taken";
}else {
table for users
It goes to the else and adds the username to the database anyways. I have checked to make sure there isn't more than one username, although a greater than sign would work better anyway. any ideas?
Your code must be using parameter binding to send the value of $username to the database, otherwise "$username" is treated as a literal string. It will also protect your from SQL injections.
It would probably be better to create a UNIQUE key on that column instead. If you want to do it in the application layer for whatever reason, you can fetch the result and use that.
$stmt = $con->prepare('SELECT * FROM users WHERE username = ?');
$stmt->bind_param('s', $username);
$stmt->execute();
$result = $stmt->get_result()->fetch_all();
if ($result) {
echo "Username is taken";
} else {
// No such username in the database yet
}
This is not going to be very efficient, so we can simplify it using COUNT(1). It will return a single value containing the number of matching rows.
$stmt = $con->prepare('SELECT COUNT(1) FROM users WHERE username = ?');
$stmt->bind_param('s', $username);
$stmt->execute();
$usernameTaken = $stmt->get_result()->fetch_row()[0];
if ($usernameTaken) {
echo "Username is taken";
} else {
// No such username in the database yet
}
For more explanation see https://phpdelusions.net/mysqli/check_value
$s = 'SELECT * FROM users WHERE username = "$username"';
You are using double quote inside single quote so there is no interpolation happening. Change the order to
$s = "SELECT * FROM users WHERE username = '{$username}'";

Why is my mysqli_fetch_assoc not grabbing the row info so I can insert details into my table?

First off, I know about sql injection and that my code is not foolproof, prone to injection etc. Will be working on that next.
Now : from my Android app to my PHP file I submit a JSON array of phone numbers like :
[{"phone_number":"+12345678"},
{"phone_number":"+23456789"},
{"phone_number":"34567890"},
{"phone_number":"45678901"}
etc... etc...
These are contacts in my app user's phone. If these contacts are people who are also users of my app then I want to insert those numbers into my contacts table.
But I can't get it to work. mysqli_fetch_assoc isn't working correctly. I don't know why.
In my contacts table I have 3 columns - an auto increment, user_id and contact_id. The first two values are inserted correctly but the contact_id is always put in as '0', which is wrong.
Here is my code :
require('dbConnect.php');
//this is me, +567890123, my user_id in the user table
$user_id = '20';
//post all contacts in my phone as a JSON array
$json = $_POST['phonenumber'];
$array = json_decode($json);
foreach ($array as $value) {
$phonenumber = $value->phone_number;
$sql = "SELECT username FROM user WHERE username = '$phonenumber'";
$result = mysqli_query($con, $sql);
$num_rows = mysqli_num_rows($result);
if ($num_rows > 0) {
echo "phonenumber is " . $phonenumber . "<br>";
// we want to put $phonenumber in the contacts table, as one of +567890123 contacts
// In the user table get the associated rows of $phonenumber
while ($row = mysqli_fetch_assoc($result)) {
// get the associated user_id in that row, that's what we want to put into the contacts table
$contact_id = $row['user_id'];
$insert_into_contacts_command = "INSERT INTO contacts VALUES(NULL, '$user_id','$contact_id')";
$insert_into_contacts_table = mysqli_query($con, $insert_into_contacts_command);
}
} //if +353864677745 is NOT in the user table...
else {
echo 'not a match.';
}
}
$contact_id = $row['user_id'];
Here $contact_id will be null, because you are trying to access not existing field $row['user_id'] of the $row .
Actually there is only one field username in your results set, as you specified:
$sql = "SELECT username FROM user WHERE username = '$phonenumber'";
Try to change your query to this:
$sql = "SELECT user_id, username FROM user WHERE username = '$phonenumber'";
Your query selects the column username, not userid.
You haven't posted anything about the table user, so it's hard to suggest a new query, but I guess it's the following:
$stmt = mysqli_prepare($con, "SELECT userid FROM user WHERE username = ?");
$stmt->bind_param("s", $phonenumber);
$stmt->execute();
$stmt->bind_result($userid);
while ($stmt->fetch()) {
// Work with $userid
}
You'll note that this uses a prepared statement with a bound parameter. That way, your code is not prone to SQL injections.

Comparing if values exists in a MySQL table using PHP

Given the following code:
$checkuname = $connect->prepare('SELECT * FROM user WHERE username = ?');
$checkuname->bind_param("s", $uname);
$checkemail = $connect->prepare('SELECT * FROM user WHERE email = ?');
$checkemail->bind_param("s", $email);
$match = 0;
if ($checkuname->execute()) {
//if username matches//
$erroruname = "This username exists, please enter a new one";
$match = $match + 1;
}
if ($checkemail->execute()) {
//if email matches//
$erroremail = "This email has been used, please enter another one";
$match = $match + 1;
}
if ($match == 0) { //if no match, good to push data into database// }
No matter what happens, it always returns me saying that username exists (when it doesn't).
Is there any way to correct this?
Or if you think there would be an easier or clearer way to check if both username and email exists in a database, please do share too.
Just to mention too: Most tutorials I have found uses a single variable to check, but I need to check 2 variables
"#Fred-ii- I'll invite you to post an answer and I'll mark it as solved – Timothy Wong Glash"
As requested by the OP:
You can do this in one query.
$query = "SELECT `email`, `username` FROM `user` WHERE email=? AND username=?";
if ($stmt = $connect->prepare($query)){
$stmt->bind_param("ss", $email, $uname);
if($stmt->execute()){
$stmt->store_result();
$email_check= "";
// Number of binded results must match the number of columns in SELECT
$stmt->bind_result($email_check, $username_check);
$stmt->fetch();
// or num_rows >0
if ($stmt->num_rows == 1){
echo "That records already exists.";
exit;
}
}else{ echo "Error: " . mysqli_error($connect); }
}
Well, you are checking if the query executes, but you are not checking if the values returned are correct or not. What you need to do is verify how many rows are returned after executing the query, if a row is returned the user has been found. You can do that with num_rows.

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