variables are not output from mysqli statement after binding - php

I'm trying to select things from my database and echo them. For some reason the only thing I can echo is the email. The id and the username doesn't show up. I don't get any errors, they just don't appear.
$sql = "SELECT id, email, username FROM users WHERE email = ?";
if ($stmt = mysqli_prepare($link, $sql)) {
mysqli_stmt_bind_param($stmt, "s", $param_email);
$param_email = $email;
if (mysqli_stmt_execute($stmt)) {
mysqli_stmt_store_result($stmt);
if (mysqli_stmt_num_rows($stmt) == 1) {
mysqli_stmt_bind_result($stmt, $id, $email, $username);
$error = 0;
$to = $email;
echo "id:".$id;
echo $username;
echo $email;
} else {
//some stuff
}
} else {
$error = 1;
}
}
What Am I missing?

The reason why you cannot see any values fetched from the database is because you forgot to call fetch() after bind_result().
However, you are overcomplicating things. You do not need so many if statements and you should not use bind_result() if you have more than one column. This gets very messy. Use get_result() to fetch the results and then fetch the single row you need(assuming email is unique and your SELECT returns 0 or 1 records).
$stmt = $link->prepare("SELECT id, email, username FROM users WHERE email = ?");
$stmt->bind_param('s', $email);
$stmt->execute();
$result = $stmt->get_result()->fetch_assoc();
if ($result) {
$error = 0;
$to = $result['email'];
echo "id:".$result['id'];
echo $result['username'];
echo $result['email'];
} else {
$error = 1;
}
There is no need for mysqli_stmt_num_rows. The data itself tells you if something was returned or not. This also protects you from a similar problem when using unbuffered queries. It is easy to accidentally omit mysqli_stmt_store_result().
Never check the return value of mysqli_stmt_execute() or mysqli_prepare(). This is a terrible and messy practice. Ensure you have error reporting switched on. See How to get the error message in MySQLi?

Related

why is $stmt -> num_rows returning 0 when login exists?

Making a login form and this is my first time using prepared statements. My issue is the num_rows keeps returning 0, despite entering the correct email and password that matches the email and password of my table. I tested that the connection works and the SQL statement works also, its just the num_rows is always 0.
PHP(without php tags and connection code):
$email = $_POST['email'];
$password = md5($_POST['password']);
if(!($stmt = $con->prepare("SELECT `email`, `password` FROM users WHERE `email` = ? AND `password` = ?")))
{
echo "Prepare failed: (" . $con->errno . ")" . $con->error;
}
else
{
echo " Query read \n";
$stmt->bind_param('ss', $email, $password);
$stmt->execute();
$stmt->store_result();
$num_of_rows = $stmt->num_rows;
$stmt->bind_result($email, $password);
echo $num_of_rows;
if($num_of_rows == 1) //To check if the row exists
{
echo "Exists";
if($stmt->fetch()) //fetching the contents of the row
{
echo "Exists";
$_SESSION['loggedin'] = true;
$_SESSION['message'] = "logged in";
$_SESSION['email'] = $email;
echo "Success!";
exit();
}
}
else
{
echo "Error";
}
}
Hopefully I've just forgotten something, but either way I am stumped.
Thanks in advance!
The value returned by num_rows may not be a valid count of rows returned until all of the rows are retrieved. That's the case for a mysqli_result. The documentation makes it appear that the num_rows function of a mysqli_stmt should be available immediately after a store_result.
Seems like the most reasonable explanation for the behavior is that the query did not return a row.
Documentation:
http://php.net/manual/en/mysqli-result.num-rows.php
http://php.net/manual/en/mysqli-stmt.num-rows.php
Why do we need to use num_rows at all? That just seems like a lot of unneeded clutter. We could just do the fetch. If it returns TRUE, we know there was at least one row returned. If it's FALSE, then zero rows were returned. No need to muck with num_rows.
If we are going to use store_result, its a good pattern to follow that with a free_result once we're done with the resultset
Also, do not use MD5 for password hash. And there's no need to return the password hash from the database, we can omit that from the SELECT list.
https://security.stackexchange.com/questions/19906/is-md5-considered-insecure
as mentioned ditch out, my_num_rows, and store_result, below works for me.
$email = $_POST['email'];
$password = $_POST['password'];
$arr = array();
$stmt = $db->prepare("SELECT email, password FROM users where email = :email
and password = :password");
$stmt->bindParam(":email", $password);
$stmt->bindParam(":password", $password);
$stmt->execute();
$arr = $stmt->fetchAll();
if(!$arr) exit('No rows');
print_r($arr);
$stmt = null;
You also want to fetch the results, like this:
$stmt->bind_param('ss', $email, $password);
$stmt->execute();
$stmt->store_result();
$stmt->fetch();
$num_of_rows = $stmt->num_rows;
$stmt->bind_result($email, $password);
echo $num_of_rows;

check username and email exist in database or not in mysql

$valid = mysqli_query($com,"select username,email from company_profile where username = ".$uname." or email = ".$email." ");
if ($valid=="")
{echo "email n username exists";}
else
{
echo "reg success";
}
Here is my code, it doesn't work is i was also sure. want to return result weather email or username exists in db or not.
what's the way to do it.
The mysqli_query method returns a resultset, not a scalar.
$result = mysqli_query($com, "SELECT ...", MYSQLI_STORE_RESULT);
if ( $result->num_rows() > 0 ) {
echo "query returned at least one row";
}
The code looks vulnerable to SQL injection, we don't see any references to the mysqli_real_escape_string function.
We'd prefer to see a prepared statement with bind variables, e.g.
if ($stmt = mysqli_prepare($com, "SELECT username,email from company_profile"
. " where username = ? OR email = ? "))
{
mysqli_stmt_bind_param($stmt, "ss", $uname, $email);
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);
while ($row = mysqli_fetch_array($result))
{
}
mysqli_stmt_close($stmt);
}

Why is fetch_assoc returning false?

$stmt = $mysqli->prepare("SELECT username, email, password, code FROM temp_users WHERE code = ?");
$stmt->bind_param('s', $code);
$stmt->execute();
$stmt->store_result();
//if SELECT statement returns 1, grab data.
if ($stmt->num_rows === 1) {
echo "Got Row";
$result = $stmt->get_result();
var_dump($result);
while ($row = $result->fetch_assoc()) {
$username = $row['username'];
$email = $row['email'];
$password = $row['password'];
}
This is really weird, the query must be going through because the script is echoing "Got Row", and I have no errors up to that point. But when I try to use $result->fetch_assoc() I get an error,and $result is spitting out false, so why is that? Please excuse how dumb this question may seem, I'm still learning how to use mysqli. :)
Your question is neither dumb nor weird. You are simply confused by store_result() and get_result().
Both of these functions fetch the whole record set from the database. Once the data is fetched you can't fetch it again. Therefore, you can't use both of these functions at the same time!
We can fix your code in two ways.
With store_result():
$stmt = $mysqli->prepare("SELECT username, email, password, code FROM temp_users WHERE code = ?");
$stmt->bind_param('s', $code);
$stmt->execute();
$stmt->store_result();
//if SELECT statement returns 1, grab data.
if ($stmt->num_rows === 1) {
echo "Got Row";
$stmt->bind_result($username, $email, $password);
while ($stmt->fetch()) {
// use the data here
var_dump($username);
}
}
with get_result():
$stmt = $mysqli->prepare("SELECT username, email, password, code FROM temp_users WHERE code = ?");
$stmt->bind_param('s', $code);
$stmt->execute();
$result = $stmt->get_result();
//if SELECT statement returns 1, grab data.
if ($result->num_rows === 1) { // <--- !!! We are using the result object here
echo "Got Row";
foreach ($result as $row) {
$username = $row['username'];
$email = $row['email'];
$password = $row['password'];
}
}

I keep getting this error on my insert "call to undefined method mysqli_stmt::get_result()" [duplicate]

This question already has answers here:
Fatal error: Call to undefined method mysqli_stmt::get_result()
(2 answers)
Closed 9 years ago.
I'm not sure why I keep getting this error but I need some help with it... I'm just trying to check the db to see of the record exists before allowing an insert.
$input_errors = array();
if (!empty($_POST['username'])) {
$user = $_POST['username'];
} else {
$input_errors['username'] = "Must fill out username";
}
$email = filter_input(INPUT_POST, 'usermail', FILTER_VALIDATE_EMAIL);
if (false === $email) {
$input_errors['usermail'] = "Not a valid email address";
}
if(count($input_errors) > 0) {
print_r($input_errors); die();
}
$sql = "SELECT COUNT(*) as amount FROM people WHERE username = ?
OR email = ?";
if ($stmt = $mysqli->prepare($sql)) {
$stmt->bind_param("ss", $user, $email);
$stmt->execute();
$results = $stmt->get_result();
$data = mysqli_fetch_assoc($results);
if ($data['amount'] > 0)
{
print "User already exists";
}
}
else {
$stmt = $mysqli->stmt_init();
if (!$stmt) {
echo "Init failed";
} else {
$cmd = "INSERT INTO people (username, email, sign_up_date) VALUES (?, ?, NOW() )";
if ($stmt->prepare($cmd)) {
$stmt->bind_param('ss', $user, $email );
$stmt->execute();
echo $stmt->affected_rows . " row(s) inserted";
$stmt->close();
} else {
echo "Prepare failed";
}
mysqli_close($mysqli);
}
}
If anyone can lend a helping hand that would be fantastic.
For some reason I just can't stand such long and windy codes.
All you actually need is just
$cmd = "INSERT IGNORE INTO people (username, email, sign_up_date) VALUES (?, ?, NOW() )";
$stmt->prepare($cmd);
$stmt->bind_param('ss', $user, $email);
$stmt->execute();
if (!$stmt->affected_rows)
{
print "User already exists";
}
No need to hassle with extra select query.
No need to hassle with binding results.
No need to hassle with numerous nested if statements (whose logic is flawed and actually spoiled the whole mess).
Make sure your php version is PHP 5.3.0 or higher and you have the mysqlnd driver installed on your server. Otherwise, that function is not available.
Instead, you could use fetch().

Check if user exists in database

I've made a user class which validates the data passed through the form and then subsequently updates the database table users. I want to add extra functionality such as checking if the username and email exists in the table, I've added a little script however it doesn't seem to be working.
I inserted a duplicated email address and I did not get the error message "email exists" instead I get the success message "1 row inserted":
Am I doing something wrong below? Is there perhaps a better way to approach this?
public function insert() {
if (isset($_POST['submit'])) {
$email = isset($_POST['email']) ? $this->mysqli->real_escape_string($_POST['email']) : '';
$result = $this->mysqli->prepare("SELECT * FROM users WHERE email='".$email."'");
if ($result->num_rows) {
echo "email exisits!";
}
else
{
$stmt = $this->mysqli->prepare("INSERT INTO users (username, password, name, email) VALUES (?, ?, ?, ?)");
$stmt->bind_param('ssss', $username, $password, $name, $email); // bind strings to the paramater
//escape the POST data for added protection
$username = isset($_POST['username']) ? $this->mysqli->real_escape_string($_POST['username']) : '';
$cryptedPassword = crypt($_POST['password']);
$password = $this->mysqli->real_escape_string($cryptedPassword);
$name = isset($_POST['name']) ? $this->mysqli->real_escape_string($_POST['name']) : '';
$email = isset($_POST['email']) ? $this->mysqli->real_escape_string($_POST['email']) : '';
/* execute prepared statement */
$stmt->execute();
printf("%d Row inserted.\n", $stmt->affected_rows);
/* close statement and connection */
$stmt->close();
}
You are using the worst API you ever can choose.
With safeMysql it would be
$exists = $this->db->getOne("SELECT 1 FROM users WHERE email=?s", $_POST['email']);
if ($exists) {
echo "email exisits!";
}
With PDO it is slightly longer but usable
$stmt = $this->db->prepare("SELECT 1 FROM users WHERE email=?");
$stmt->execute(array($_POST['email']));
$exists = $stmt->fetchColumn();
if ($exists)
{
echo "email exisits!";
}
But with raw mysqli you will need a screenful of code only to check if user exists.
So, the whole function using safeMysql would be
public function insert()
{
if (!isset($_POST['submit'])) {
return FALSE;
}
$sql = "SELECT 1 FROM users WHERE email=?s";
$exists = $this->db->getOne($sql, $_POST['email']);
if ($exists)
{
echo "email exisits!";
return FALSE;
}
$sql = "INSERT INTO users SET ?u";
$allowed = array('username', 'name', 'email');
$insert = $this->db->filterArray($_POST, $allowed);
$insert['password'] = crypt($_POST['password']);
$this->db->query($sql, $insert);
return $this->db->afectedRows();
}
you need to use this code after prepare statement
$stmt->execute();
$stmt->store_result();
put this
if ($result->num_rows > 0) {
echo "email exisits!";
}
instead of
if ($result->num_rows) {
echo "email exisits!";
}
First, you are using prepare (great!) but then you are just passing in the value of email, effectively defeating the benefit of prepared statements.
Second, you never execute the query, which is why you don't get anything in num_rows.
public function insert() {
$result = $this->mysqli->prepare("SELECT COUNT(*) FROM users WHERE email=?");
$result->bind_param("s", $_POST['email']);
$result->execute();
$result->bind_result($email_count);
if ($email_count) {
echo "email exisits!";
} else {
# your other logic
From what I can see you're not assigning a value to num_rows prior to testing it with if ($result->num_rows), so it will always be 0

Categories