MYSQLi num_rows always returns 0 [duplicate] - php

This question already has an answer here:
Why does mysqli num_rows always return 0?
(1 answer)
Closed 1 year ago.
I am still new in the PHP and MySQL. I just started to learn MySQLi before few days and I met this problem.
This page is named login.php. The problem is that the query return 0 num rows.
When I run the query in phpmyadmin it show this message and 1 row.
Showing rows 0 - 0 (1 total, Query took 0.0010 sec)
Image:
Here is my code:
<?php
session_start();
require 'config.php';
$username = $_POST['username'];
$password = $_POST['password'];
$salt = 'qwerty';
$pass_prepare = md5($salt).sha1($password);
if ($_SERVER['REQUEST_METHOD'] != "POST") {
header('Location: index.php');
}
if (isset($username) && isset($pass_prepare)) {
$stmt = mysqli_prepare($db_con, "SELECT user_id, username, password, rank, last_activity FROM imes_users WHERE username=? AND password=? LIMIT 1");
mysqli_stmt_bind_param($stmt, "ss", $username, $pass_prepare);
mysqli_execute($stmt);
mysqli_stmt_bind_result($stmt, $user_id, $username1, $password1, $rank, $last_activity);
mysqli_stmt_fetch($stmt);
echo mysqli_num_rows($stmt);
} else {
echo 'error';
}
Could you help me to fix this issue?

$sql = mysqli_query($connection, $query);
$count = $sql->num_rows; // $count contains now your value

You are using prepared statements, so the syntax is slightly different. You want to use mysqli_stmt_num_rows instead of mysqli_num_rows.
$stmt = mysqli_prepare($db_con, "SELECT user_id, username, password, rank, last_activity FROM imes_users WHERE username=? AND password=? LIMIT 1");
mysqli_stmt_bind_param($stmt, "ss", $username, $pass_prepare);
mysqli_execute($stmt);
mysqli_stmt_bind_result($stmt, $user_id, $username1, $password1, $rank, $last_activity);
mysqli_stmt_fetch($stmt);
echo mysqli_stmt_num_rows($stmt);

Related

How would I fetch for data for an email and a username? [duplicate]

This question already has answers here:
How to search multiple columns in MySQL?
(6 answers)
Closed 2 years ago.
I have found out how to fetch for a username, however how would I do this with an email? Because, I want to add two separate error messages for an email and a username
$sql = "SELECT uid_users FROM users WHERE uid_users=?";
$stmt = mysqli_stmt_init($conn);
if (!mysqli_stmt_prepare($stmt, $sql)) {
header("Location: ../register.php?error=sqlerror");
exit();
}
else {
mysqli_stmt_bind_param($stmt, "s", $username);
mysqli_stmt_execute($stmt);
mysqli_stmt_store_result($stmt);
$resultCheck = mysqli_stmt_num_rows($stmt);
if ($resultCheck > 0) {
header("Location: ../register.php?error=usertaken&mail=".$email);
exit();
}
Use OR to check another column.
$sql = "SELECT uid_users FROM users WHERE uid_users=? OR email = ?";
$stmt = mysqli_stmt_init($conn);
if (!mysqli_stmt_prepare($stmt, $sql)) {
header("Location: ../register.php?error=sqlerror");
exit();
}
else {
mysqli_stmt_bind_param($stmt, "ss", $username, $email);
mysqli_stmt_execute($stmt);
mysqli_stmt_store_result($stmt);
$resultCheck = mysqli_stmt_num_rows($stmt);
if ($resultCheck > 0) {
header("Location: ../register.php?error=usertaken&mail=".$email);
exit();
}
}
Note that this won't tell them whether it was the username or email that was already taken. If you want that, you should just do two separate queries, one that looks for a duplicate username, another that looks for a duplicate email.
Or you could change the query to SELECT uid_users, email and fetch the results of the query. Then check whether the fetched username or email matches the input, and display an appropriate error.
You can use the OR operator for this:
SELECT uid_users
FROM users
WHERE uid_users=?
OR email=?";```
If you want to check if a record exists in the database that matches both username and email then you should use WHERE uid_users=? AND email=?.
If you want to check if a a record exists in the database that matches either username or email, then use WHERE uid_users=? OR email=?.
Small note, you don't need to fetch the data if you only want to check existence of the record in DB. Simply let MySQL tell you the number of matching record. Use COUNT() for this purpose.
$stmt = $conn->prepare("SELECT COUNT(1) FROM users WHERE uid_users=? OR email=?");
$stmt->bind_param('ss', $username, $email);
$stmt->execute();
// Fetch value of COUNT(1) from DB
$resultCheck = $stmt->get_result()->fetch_row()[0];
if ($resultCheck) {
header("Location: ../register.php?".http_build_query(['error' => 'usertaken', 'mail' => $email]));
exit();
}

Why can't I get data from SQL row using PHP prepared statements?

Connection is good. I can insert into the database, and check if a row exists by checking if results > 0, but I can not select row data. The $email's being tested are in the database.
Ex 1.
require 'connection/connection.php';
$email = "sample#sample.com";
$sql = "SELECT * FROM users WHERE user_email=?"; // SQL with parameters
$stmt = $conn->prepare($sql);
$stmt->bind_param("s", $email);
$stmt->execute();
$result = $stmt->get_result(); // get the mysqli result
$user = $result->fetch_assoc(); // fetch data
echo $user['user_name'];
Ex. 2
$email = "james#james.com";
$sql = "SELECT * FROM users WHERE user_email=?";
$stmt = mysqli_stmt_init($conn);
mysqli_stmt_bind_param($stmt, "s", $email);
mysqli_stmt_execute($stmt);
After inserting an echo after every line one by one, this is as far as it gets. If an echo statement is placed after the next line it will not appear.
$result = mysqli_stmt_get_result($stmt);
if ($row = mysqli_fetch_assoc($result)) {
$_SESSION['active_user_id'] = $row['user_id'];
} else {
header("Location: https://example.com/");
exit();
}
The problem was fixed through cPanel. I had to switch from "mysqli" to "nd_mysqli." This fixed the problem right away.
I found the instructions to do this here https://www.plus2net.com/php_tutorial/mysqli_mysqlnd.php
I hope this helps others with the same problem.

mysqli_stmt_num_rows with prepared statement doesn't return number of rows [duplicate]

This question already has an answer here:
Why does mysqli num_rows always return 0?
(1 answer)
Closed 1 year ago.
Prepared statement returns 0 rows when it should return a row:
My code:
$conn = mysqli_connect("localhost", "root", "", "test1");
$myUser = "qqq";
$stmt = mysqli_stmt_init($conn);
$sql = 'SELECT `userMail` FROM `users` WHERE `userName`=? LIMIT 1';
mysqli_stmt_prepare($stmt, $sql);
mysqli_stmt_bind_param($stmt, "s", $myUser);
mysqli_stmt_execute($stmt);
$myresult = mysqli_stmt_num_rows($stmt);
die(nl2br("myUser = ".$myUser."\nmyresult = ".$myresult));
My data:
The output:
Where am I wrong...?
$myresult should be 1, for there IS such a row...
As you have already correctly noticed you need mysqli_stmt_store_result($stmt); after mysqli_stmt_execute($stmt);.
As per PHP docs:
If you use mysqli_stmt_store_result(), mysqli_stmt_num_rows() may be called immediately.
However, I need to point out that you don't need it, or in fact you do not need to use mysqli_stmt_num_rows() at all. I don't think I ever had to use this function myself neither.
What you are trying to achieve is to check if a particular row exists in DB. This can be done as mentioned here: https://phpdelusions.net/mysqli/check_value
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$conn = new mysqli("localhost", "root", "", "test1");
$myUser = "qqq";
$sql = 'SELECT 1 FROM `users` WHERE `userName`=? LIMIT 1';
$stmt = $conn->prepare($sql);
$stmt->bind_param('s', $myUser);
$stmt->execute();
$exists = (bool) $stmt->get_result()->fetch_row();
die(nl2br("myUser = ".$myUser."\nmyresult = ".$exists));
Of course instead of (bool) $stmt->get_result()->fetch_row() you could use (bool) $stmt->get_result()->num_rows.

Prepare Statement not fetching/binding any result. PHP [duplicate]

This question already has answers here:
Can I parameterize the table name in a prepared statement? [duplicate]
(2 answers)
What to do with mysqli problems? Errors like mysqli_fetch_array(): Argument #1 must be of type mysqli_result and such
(1 answer)
Closed 4 years ago.
I wanted to make this query with a prepare statement, but somehow it doesnt fetch any data. The username I type in the form is in the database, I guess the problem must be somewhere in the prepare stmt.
if(isset($_POST['login'])){
$typed_username = mysqli_real_escape_string($connection, $_POST['login_username']);
$typed_password = $_POST['login_password'];
$column = "username";
$stmt = mysqli_prepare($connection, "SELECT user_password FROM users WHERE ? = ?");
mysqli_stmt_bind_param($stmt, "ss", $column, $typed_username);
mysqli_stmt_execute($stmt);
mysqli_stmt_bind_result($stmt, $user_password);
if(mysqli_stmt_num_rows($stmt) < 1){
echo "no results";
}
if(password_verify($typed_password, $user_password)){
echo "login yeah!";
}
}
I get "no results" no matter what I try.
Although I've added a comment on how to solve this, I guess for your learning purpose I should add the solution here.
This becomes a very simple solution if $column = "username"; never changes.
If this is the case; you must change your prepare from this:
$stmt = mysqli_prepare($connection, "SELECT user_password FROM users WHERE ? = ?");
to this:
$stmt = mysqli_prepare($connection, "SELECT user_password FROM users WHERE username = ?");
Following that change, you no longer need to bind $column (mysql says binding a column is pointless anyway because it won't accept it.)
So your bind_param changes from:
mysqli_stmt_bind_param($stmt, "ss", $column, $typed_username);
to this (you no longer need to myqsli_real_escape_string so you can throw the $_POST directly into the query:
mysqli_stmt_bind_param($stmt, "s", $_POST['login_username']);
Therefore, your overall code now looks like:
if(isset($_POST['login'])){
$typed_password = $_POST['login_password'];
$stmt = mysqli_prepare($connection, "SELECT user_password FROM users WHERE username = ?");
mysqli_stmt_bind_param($stmt, "s", $_POST['login_username']);
mysqli_stmt_execute($stmt);
mysqli_stmt_bind_result($stmt, $user_password);
//you where missing fetch
mysqli_stmt_fetch($stmt);
//store the result
mysqli_stmt_store_result($stmt);
//now we can use mysqli_stmt_num_rows
if(mysqli_stmt_num_rows($stmt) < 1){
echo "no results";
}
//added an else here as I said in the comments
else if(password_verify($typed_password, $user_password)){
echo "login yeah!";
}
}

PHP PDO how do i include fetch assoc and numrows

trying to convert all my old mysql_* operations into new and, from what i've heard, improved PDO, but this query wont seem to run successfully, I am trying to select all from the table PEOPLE where the username = $username (which has previously been declared $username = $_SESSION['username'];)
$query = "SELECT * FROM people WHERE username=?";
$stmt = $conn->prepare($query);
$stmt->bindParam(1, $username);
$stmt->execute();
$num_rows = $stmt->fetchColumn();
if ($num_rows == 1) {
// ...
}
THE WORKING CODE IS:
$query = "SELECT * FROM people
WHERE username=?";
$stmt = $conn->prepare($query);
$stmt->bindParam(1, $username);
$stmt->execute();
$num_rows = $stmt->fetchColumn();
$user = $stmt->fetchObject();
if ($user) {
//do something
}
$stmt->fetchColumn does not fetch the number of rows; in this case it will fetch the first column from the first row of the result set. Since that will not be equal to 1 generally your test will fail.
In this case there is also no real need to count the number of returned rows because you are expecting either one or zero (if the username does not exist). So you can simply do:
$stmt->execute();
$user = $stmt->fetchObject();
if (!$user) {
// not found
}
else {
echo "User $user->username found!";
}
The if(!$user) test works because if there is no row to fetch $user will be false (see the documentation for fetchObject).
$query = "SELECT * FROM people WHERE username = :username";
$stmt = $conn->prepare($query);
$stmt->bindParam(':username', $username);
$stmt->execute();
while ($row = $stmt->fetchObject()) {
// do stuff
}
Use PDOStatement::rowCount as the num_rows and PDOStatement::fetch(PDO::FETCH_ASSOC) as fetch_assoc equivalent.
You want
if ($stmt->num_rows == 1) {
instead.

Categories