"bind_param" returning 0 rows [duplicate] - php

This question already has answers here:
Single result from database using mysqli
(6 answers)
Closed 2 years ago.
I have a query with a parameter to bind stored in the session.
I tested the query on the database and it should return 1 row but it does not!
I tried everything. Its not an issue with the $id because I use it for another query and it is fully working:
$resultReturn = $con->prepare( 'SELECT `returns`.`return_id`, `returns`.`return_status` FROM
`agents` LEFT JOIN `returns` ON `returns`.`agent_id` = `agents`.`id` AND `agents`.`id` = ?');
$resultReturn->bind_param('i', $id);
$resultReturn->execute();
$resultReturn->fetch();
$resultReturn->store_result();
$resultReturn->bind_result($returnID, $returnStatus);
if($resultReturn)
{
echo $resultReturn->num_rows; //zero
while($row = $resultReturn->fetch_row())
{
echo $resultReturn->num_rows; //incrementing by one each time
}
echo $resultReturn->num_rows; // Finally the total count
}
$con -> close();
the first if returns always FALSE; If I set manually the id it works!
Here is my other query at the beginning of the same page (and its perfectly working):
$con = mysqli_connect($DATABASE_HOST, $DATABASE_USER, $DATABASE_PASS, $DATABASE_NAME);
if (mysqli_connect_errno()) {
exit('Failed to connect to MySQL: ' . mysqli_connect_error());
}
// We don't have the password or email info stored in sessions so instead we can get the results from the database.
$stmt = $con->prepare('SELECT password, email, role FROM agents WHERE id = ?');
// In this case we can use the account ID to get the account info.
$stmt->bind_param('i', $id);
$stmt->execute();
$stmt->bind_result($password, $email, $role);
$stmt->fetch();
$stmt->close();
It is because I'm using the same connection for multiple queries?

Move fetch() after bind_result().
The correct order should be:
$resultReturn = $con->prepare(/* */);
$resultReturn->bind_param('i', $id);
$resultReturn->execute();
$resultReturn->store_result();
$resultReturn->bind_result($returnID, $returnStatus);
$resultReturn->fetch();

Related

PHP: Insert into MySQL database and check if already existing - with binding parameters

I am trying to insert test data into a MySQL database using the below lines which works fine so far.
1) How can I check whether the email already exists in the database and if, echo a message? I saw references here to the use of WHERE EXISTS or mysqli_num_rows but I am not sure which and how to apply here - in combination with binding parameters.
2) I came across unset($username, $password, $database); to make this query more secure. Is that something that is needed / useful here and if, where should I put it ?
My PHP:
$conn = new mysqli($host, $username, $password, $database);
if($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$stmt = $conn->prepare("INSERT INTO cust (email, pw) VALUES (?, ?)");
$stmt->bind_param("ss", $email, $hashPw);
$email = "me#mail.com";
$pw = "testpw12345";
$hashPw = password_hash($pw, PASSWORD_DEFAULT);
$stmt->execute();
echo "Success";
$stmt->close();
$conn->close();
An alternative to the solution proposed already.
$stmt = $conn->prepare("SELECT COUNT(1) FROM cust WHERE email = ?");
$stmt->bind_param("s", $email);
$stmt->execute();
$emailExists = $stmt->get_result()->fetch_row()[0];
if ($emailExists) {
echo "This email address is already in use";
} else {
// continue with insert code
}
This approach does not require you to close the statement. Once you execute get_result the statement data is fetched in full.
This solution also has a potential performance benefit. If your table contains many columns with many data, then fetching that data just to check if a record exists is a waste of CPU. Simply fetch COUNT(1) and check the single column of the single returned record. If it is 0, the value is falsish, if it is more than your if statement will evaluate to true and a message will be displayed. I would also strongly recommend to structure your code in such a way that you rarely have to use exit.
To check if the email already exists in the database, just try to select a row with it in:
$stmt = $conn->prepare("SELECT * FROM cust WHERE email = ?");
$stmt->bind_param("s", $email);
$stmt->execute();
$stmt->store_result();
if ($stmt->num_rows > 0) {
echo "This email address is already in use";
exit;
}
$stmt->close();
// continue with insert code
In terms of your other questions, I don't see any reason to unset variables, and using prepared queries and password_hash gives you about as good protection as you can get.

Why am I getting null results?

So i have a very simple function that runs against a MySQL database of users with a few other credentials. I have written several other functions that run similar queries with that work as expected. However currently every time I run a query against my DB i get null result. I have taken the query itself and ran it directly against it(phpmyadmin) and was able to retrieve the desired results.
function getName( $user ){
$con = mysqli_connect('localhost','*****','*****','*****');
if(mysqli_connect_error()){
echo 'Failed to Connect: '. mysqli_connect_error();
die();
}
$stmt = $con->prepare('SELECT firstName,lastName FROM users WHERE user=? LIMIT 1');
$stmt->bind_param('s',$user);
$stmt->execute();
$stmt -> bind_result($fname,$lname);
$stmt->fetch();
$lArr = str_split($lname);
$canName = $fname . ' ' . $lArr[0].'.';
return $canName;
}
I have tried with and without limit just in case. var_dump always shows null. Does anyone know why this would happen?
You forgot to ->fetch() any results from the result set, just binding them to variables is not enough
function getName( $user ){
$con = mysqli_connect('localhost','*****','*****','*****');
if(mysqli_connect_error()){
echo 'Failed to Connect: '. mysqli_connect_error();
die();
}
$stmt = $con->prepare('SELECT firstName,lastName FROM users WHERE user=? LIMIT 1');
$stmt->bind_param('s',$user);
$stmt->execute();
$stmt -> bind_result($fname,$lname);
// now fetch data into the bound variables
$stmt->fetch();
$lArr = str_split($lname);
$canName = $fname . ' ' . $lArr[0].'.';
return $canName;
}
You execute the query but you are not picking up the results (As RiggsFolly was saying). You shout use fetch() of fetchall()
http://php.net/manual/en/pdostatement.fetchall.php
http://php.net/manual/en/pdostatement.fetch.php

Display content if row == 1 if row ==0 do not display

So I have a log in script that creates a $_SESSION based on the username of the user logging in. On another page I wish to display content if the row for that user has a 1 in it. If it has a 0 in that row, then do not display the content. I am having issues here with no matter what I've tried, it does not display YES no matter the user I log in with.
test1 = 1
test2 = 0
<?
require_once 'dbinfo.php';
$sess = $_SESSION['authuser'];
$link = mysqli_connect($servername, $username, $password);
if (!$link) {
die('Could not connect: ' . mysqli_error($link));
}
mysqli_select_db($link, $database) or trigger_error(mysqli_error($link));
$acc = "SELECT username FROM admins WHERE username = '$sess'";
$result = mysqli_query($link, $acc) or trigger_error(mysqli_error($link));
ob_start();
while($row = $result->fetch_assoc())
{
if($row['access'] == 1)
{
echo 'YES';
}
elseif ($row['access'] == 0)
{
echo 'NO';
}
}
ob_end_flush()
?>
The solution was easy and Class pointed it out. Forgot to SELECT access... instead of username. Rookie mistake.
You have to write
session_start();
in all of your files that want to make use of $_SESSION .
And your select query will only output the username column, as you have selected only this one, try it with
SELECT * FROM admins WHERE username = '$sess'
or
SELECT username, access FROM admins WHERE username = '$sess'
instead.
What you absolutely should do is learning prepared statements, as your actual query is wide open to sql injections.
Prepared Statement example (from php.net)
if ($stmt = $mysqli->prepare("SELECT District FROM City WHERE Name=?")) {
$stmt->bind_param("s", $city);
$stmt->execute();
$stmt->bind_result($district);
$stmt->fetch();
$stmt->close();
}
$mysqli->close();
You can read more about mysqli prepared statements here
write access (column) and Try using isset() function and the operator === when you get 0 in a returned variable.

->num_rows doesn't work correctly [duplicate]

This question already has answers here:
PHP MYSQLI number of rows doesnt work no errors
(3 answers)
Closed 6 years ago.
I don't understand why $amountOfUsers is showing as 0?
This used to work before I moved to the bind_param function... I was only using query() instad of prepare. But this is a lot safer, I just have trouble understand why this doesn't work, and how to fix it.
$stmt = $mysqli->prepare("SELECT id, expire, status, username FROM username WHERE username= ?");
$stmt->bind_param('s', $username);
$stmt->execute();
//Counting results. 0 = Invalid, 1 = Valid
$amountOfUsers = $stmt->num_rows;
The error I am getting is: $amountOfUsers isn't counting the number of results properly.
$stmt = $mysqli->prepare("SELECT id, expire, status, username FROM username WHERE username= ?");
$stmt->bind_param('s', $username);
$stmt->execute();
// Store the result (so you can get the properties, like num_rows)
$stmt->store_result();
// Get the number of rows
$amountOfRows = $stmt->num_rows;
// Bind the result to variables
$stmt->bind_result($id, $expire, $status, $db_username);
// Process the variables
while($stmt->fetch()) {
printf("%d %s %s %s\n", $id, $expire, $status, $db_username);
}
Sometimes things don't go according to plan. Checking result codes and errors available in your library is usually more efficient for troubleshooting than asking strangers, but hopefully this stranger can help... choose one of these patterns:
A:
$result = $stmt->execute();
if (!$result) { /* handle errors */ }
B:
$stmt->execute();
if ($stmt->errno != 0) { /* handle errors */ }
C (for development troubleshooting only, not code you would leave around):
$stmt->execute();
print_r($stmt->error_list);
More info here and associated pages:
http://www.php.net/manual/en/mysqli-stmt.errno.php
I would never in my life understand why php users are so inclined to the number of rows returned.
Especially if used only as a flag... if any data returned!
Why not to take the very returned data and see?
$sql ="SELECT id, expire, status, username FROM username WHERE username= ?s";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param('s', $username);
$stmt->execute();
$res = $stmt->get_result();
$row = $res->fetch_assoc();
if ($row)
{
// do whatever
}
I would never understand an inclination to long and windy codes as well.
Why not to get yourself an abstraction library and get everything in one single line?
$sql = "SELECT id, expire, status, username FROM username WHERE username= ?";
if ($row = $db->getRow($sql))
{
// do whatever
}

WHERE statement inside if condition in SQL

Can I do a WHERE clause inside an IF statement?
Like I want something like this:
$SQL = mysql_query("SELECT * FROM `table` ORDER BY `row` DESC");
$rows = mysql_fetch_array($SQL);
$email = $_SESSION['email_of_user'];
if($rows["row"] == "1" WHERE `row`='$email' : ?> (Pulls the logged in user's email)
Edit Server
<?php else : ?>
Add Server
<?php endif; ?>
Do I need (" where the WHERE statement is? Because I tried that and it didn't seem to work...
Or can I do it with an if condition inside of a where clause? Not sure of all these terms yet so correct me if I'm wrong...
You cannot mix up a query statement with PHP's statement. Instead write a query extracting desired results and check if there are any rows from that query.
I will show you an example:
$query = "SELECT * FROM `TABLE_NAME` WHERE `field` = '1' && `email`='$email'"; //Create similar query
$result = mysqli_query($query, $link); //Query the server
if(mysqli_num_rows($result)) { //Check if there are rows
$authenticated = true; //if there is, set a boolean variable to denote the authentication
}
//Then do what you want
if($authenticated) {
echo "Edit Server";
} else {
echo "Add Server";
}
Since Aaron has shown such a effort to encourage safe code in my example. Here is how you can do this securely. PDO Library provides options to bind params to the query statement in the safe way. So, here is how to do it.
$dbh = new PDO('mysql:host=localhost;dbname=test', $user, $pass); //Create the connection
//Create the Query Statemetn
$sth = $dbh->prepare('SELECT * FROM `TABLE_NAME` WHERE field = :field AND email = :email');
//Binds Parameters in the safe way
$sth -> bindParam(':field', 1, PDO::PARAM_INT);
$sth -> bindParam(':email', $email, PDO::PARAM_STRING);
//Then Execute the statement
$sth->execute();
$result = $sth->fetchAll(); //This returns the result set as an associative array

Categories