Debug mySQLi prepared statement -> email not found - php

i try to implement a register form and try to check via php and jQuery if a user already registered with a certain email.
here is my piece of code:
if(endsWith($email, 'domain.tld'))
{
$result = $database->prepare("SELECT id FROM users WHERE email LIKE ?");
$result->bind_param('s', $email);
//echo $email;
$result->execute();
//echo $result->execute();
//echo $result->num_rows;
//exit();
if($result->num_rows == 0)
{
echo'ok';
}
else {
echo 'duplicate';
}
$result->close();
}
else {
echo 'validation failed';
}
I used the commented echos and exit() to debug my code. The problem is that the database holds the user user#domain.tld and the script shows me in the echo "user#domain.tld10". So the statement ist executed successful but no rows are returned. If i execute the statement
SELECT id FROM users WHERE email LIKE "user#domain.tld"
i get the id (in this case 11) returned.
My question is, how can i debug this php script better and the biggest question is, why is my scipt not working properly?
Thank you so much in advance!

Use before num_rows
$result->store_result();
The use of mysqli_stmt_num_rows() depends on whether or not you used
mysqli_stmt_store_result() to buffer the entire result set in the
statement handle.
Docs

Related

Is there a correct way of using $stmt->close();

I have numerous statements on my website and I was wondering when and how you use $stmt->close(); correctly. Would it open vulnerabilities by leaving it open?
In this example, would the correct place to close the statement be line 23?
// First, check if the email and code exists
if (isset($_GET['email'], $_GET['code'])) {
if ($stmt = $con->prepare('SELECT * FROM accounts WHERE email = ? AND activation_code = ?')) {
$stmt->bind_param('ss', $_GET['email'], $_GET['code']);
$stmt->execute();
$stmt->store_result();
if ($stmt->num_rows > 0) {
// Account exists with the requested email and code
if ($stmt = $con->prepare('UPDATE accounts SET activation_code = ? WHERE email = ? AND activation_code = ?')) {
// Set the new activation code to 'activated', this is how we can check if the user has activated their account
$newcode = 'activated';
$stmt->bind_param('sss', $newcode, $_GET['email'], $_GET['code']);
$stmt->execute();
header('Location: messages.php?message=activated');
exit;
}
} else {
header('Location: messages.php?message=activated-error');
exit;
}
}
}
There are two statements here, would I close both? Or do I just close them both at the bottom? Also, as I am using header('Location:') does the $stmt->close(); actually get executed?
You do not need to use $stmt->close(); at all. You almost never need to close anything manually in PHP. PHP will close it for you once it is no longer needed. If you structure your code properly, PHP will close everything for you when it is most optimal.
Using header('Location:') doesn't affect mysqli objects. When you exit the code, the whole script stops and that is when PHP will close everything if it hasn't been closed yet.
You really should use some encapsulation. Don't use mysqli methods directly. Create some function or class which will abstract from this interface and it will be easier for you to use it. If you do it properly, then you do not need to worry at all about closing the objects.

Why is my sql prepared statement not giving correct responses?

I'm trying to create a login account system for my website and when a user registers, I check if there is already an account in the database. I created a function called 'check_user_exists' and here is the code for that
function check_account_exists($username, $conn){
if($stmt = $conn->prepare("SELECT * FROM users WHERE username=?")){
$stmt->bind_param('s', $username);
$stmt->execute();
echo $stmt->num_rows;
if($stmt->num_rows == 1){
return true;
}else{
return false;
}
}else{
//couldn't prepare statement
return false;
}
}
However when I go run this it returns false every time even when I know that a value in the database already exists. I haven't had any MySQL errors before this but I checked the error log and it doesn't show any errors. I added echo stmt->num_rows; but it always outputs 0. What is the matter?
Ok turns out I need to use $stmt->store_result(); after $stmt->execute(); That was preventing correct responses.

How can i check if a single mysql field is empty in php

After getting the user-info from my sql database I would like to check if some of the fields are empty and continue the script based on that. A simplified piece of code would look like this:
$userData = mysql_query("SELECT * FROM user WHERE user='".$user."' LIMIT 1");
if(mysql_num_rows($data) == 1){
$u_info = mysql_fetch_assoc($data);
if(empty($u_info['u_mobile'])){
echo 2;
exit();
} else {
echo 1;
exit();
}
} else {
echo 3;
exit();
}
The problem is the empty statement checking the recieved field. I've tried using empty(), isset(), not_null() and array_key_exists() with no luck and can't get around to what I'm doing wrong.
I also tried if($u_info['u_mobile']) == '' || $u_info['u_mobile']) == NULL) but that doesnæt work either.
Why is this, or how can I go about getting this information?
I need to collect the user-information and send them to fill out the information I don't have...
You're setting the query result to $userData but then you're using mysql_fetch_assoc($data); -- doh. You need to pass the variable that you set the query result to:
$u_info = mysql_fetch_assoc($userData);
It's OK, it is still 10AM EST so this can happen in the morning =)
I suggest that you turn on PHP error reporting. PHP would have alerted you that the array values were trying to access do not exist, saving you a lot of wasted frustration.
$userData = mysql_query("SELECT * FROM user WHERE user='".$user."' LIMIT 1");
if(mysql_num_rows($userData ) == 1){
$u_info = mysql_fetch_assoc($userData );
if(empty($u_info['u_mobile'])){
echo 2;
exit();
} else {
echo 1;
exit();
}
} else {
echo 3;
exit();
}
Please Run code..I think it will be compile better it was minor mistake

Check for username availability php

<?php
$con = mysqli_connect('localhost','root','[mypassword]','dbhwsource');
if(isset($_GET['username'])){
$username = $con->real_escape_string($_GET['username']);
$test = $con->query("SELECT username FROM users WHERE username='$username'");
if($test!=false) die("usererror");
}
if(isset($_GET['email'])){
$email = $con->real_escape_string($_GET['email']);
$test = $con->query("select * from users where email='$email'");
if($test!=false) die("emailerror");
}
$con->close();
echo "ok";
?>
So I'm just trying to check to see if the username / email is available or not, but all i get is "usererror" no matter what the input username is! I'm just frustrated and have searched for sample code everywhere and the code looks like there's nothing wrong with it. What am I doing wrong?
EDIT:
$test = $test->fetch_assoc();
if(!empty($test)) die("usererror");
This worked!
Since your query returns true, this line if($test!=false) die("usererror"); gets executed,
should be something like
$test = $con->query("SELECT username FROM users WHERE username='$username'");
$row_cnt = $test->num_rows;
if( $row_cnt > 0 ) {
//you already have user with this name, do something
}
$con->query returns a result object if the query was successful. This doesn't say anything about how many rows where found or whether the query matched anything, it just means the query executed successfully. Therefore your $test!=false test always succeeds; only in the case of a database error would it fail.
Do the query as SELECT COUNT(*) FROM ..., then fetch the first row of the result and see if the count is > 0.
I recently did something like this for an android app. you should really check this site out. It helped me tremendously. This is a detailed example of having a PHP API for an aplication. Specifically logging in.
To be specific though, here is a snippet from the page for the PHP
/*
* Check user is existed or not
*/
public function isUserExisted($email) {
$result = mysql_query("SELECT email from users WHERE email = '$email'");
$no_of_rows = mysql_num_rows($result);
if ($no_of_rows > 0) {
// user existed
return true;
} else {
// user not existed
return false;
}
}
This worked for me:
$test = $test->fetch_assoc();
if(!empty($test)) die("usererror");
Your code is really not secure not optimized anybody can login with sql injection in your code.
and your code is right as you are checking thar (test != false) it means it is true that's why your code og usererror is executing
here is some tips and always use this style for security and optimization
do same for $email
third after running the query do not check if it is true or false but check again after query
if($test->username === $_GET['username']) { do something }
check sql injections on Google why i did this

getting "mysqli num_rows Commands out of sync; you can't run this command now" error in mysql query

I'm having a problem with the a mysqli query I'm calling from a php script. I've rewritten it many times and keep getting the error: "mysqli num_rows Commands out of sync; you can't run this command now" This is the first attempt to access the database from this page. I was previously binding the parameters and then calling: $checkAcct->num_rows() and getting the same problem. I also tried what someone suggested in a different post on this site:
do { $checkAcct->use_result(); } while( $checkAcct->next_result() );
but this didn't work either and I got the same error. After I make sure a user with these details isn't in the db I execute another query to insert the user's info into the site but the error message I get pertains to this query here. Let me know if it would help to see the other query also.
Below is the code I'm trying to use:
$checkAcct = $dbConn->stmt_init();
$existingAcct = array();
if ($checkAcct->prepare("select usrName, eAddy from usr where usrName = ? OR eAddy = ?"))
{
$checkAcct->bind_param("ss", $usr, $eml);
$checkAcct->execute();
$checkAcct->bind_result($result);
while($checkAcct->fetch())
{
$existingAcct[] = $result;
}
if ($existingAcct[0] != 0)
{
if ($usr == $inputs['usrName'] && $eml == $inputs['eAddy'])
{
$acctSetupErrors[] = "Someone with your username and email address already exists. Please use the forgot password form to reset your password";
} else if ($eml == $inputs['eAddy']) {
$acctSetupErrors[] = "Someone with your email address already exists. Please use the forgot password form to reset your password or setup an account with a different email address";
} else {
$acctSetupErrors[] = "Someone with your username already exists. Please choose a different username";
}
}
$checkAcct->free_result();
$checkAcct->close();
Edit
Alright. I tried your way and it didn't work either so I went hunting for any previous db calls. I found the offending query in a db call in an include file linked higher up in the script. Funny, it's never caused problems anywhere else but now I freed the result and it works well. Thanks for your help with this. I don't have enough points to upvote you for suggesting it must be somewhere above in the code.
Can you change the above code like this and see what you are getting
$checkAcct = $dbConn->stmt_init();
$existingAcct = array();
if ($checkAcct->prepare("select usrName, eAddy from usr where usrName = ? OR eAddy = ?"))
{
$checkAcct->bind_param("ss", $usr, $eml);
$checkAcct->execute();
$checkAcct->store_result();
printf("Number of rows: %d.\n", $stmt->num_rows);
$checkAcct->free_result();
$checkAcct->close();
}
And could you make sure prepare buffer is cleared before you use it again. I hope there is some other query which is executed prior to this statement is still active in mysqli prepare statement buffer.

Categories