Mysqli - Equal and Different Expression - php

I'm having some problems with my query that is always returning false, but it should return true if not exists.
The problem is since the expression doesn't exists, it returns false.
function isRegistered($mysqli, $username, $sitename, $status){
if($stmt = $mysqli->prepare("SELECT COUNT(*) FROM table1 WHERE username= ? AND sitename = ? AND status != ?")){
$stmt->bind_param("sss", $username, $sitename, $status);
$stmt->execute();
$stmt->store_result();
if($stmt->num_rows == 0){
return true;
}else{
return false;
}
}
}
I'm after that seeking if the function is true or false. If it's false, it throws an error, if it's true, it follows for the next step. The problem is that always coming false (even if that's not true).
Basically the user only can register once in a specific area. So the first time it should be allowed, and the second time it doesn't. Could someone check what's going wrong with my query?

The number of rows for an aggregation query is always 1. If nothing matches the WHERE clause, then one row will be returned with the value of "1".
You can fix this either by changing the SELECT COUNT(*) to something non-aggregated, such as SELECT 1 or SELECT username. Or, you can read the value of COUNT(*) back from the query and use that.
I'll let you choose how to proceed.

Related

Same query but different results in phpMyAdmin and PHP [duplicate]

This question already has an answer here:
PDO, MySQL SELECT statement returning boolean true?
(1 answer)
Closed 11 months ago.
I have seen similar posts to this one already existing but none of them have helped.
When I run this PHP code with $retrievestat = 1, I get a value of 1 return by the search query in php:
$retrievestat = $_POST["statIdentifier"];
echo $retrievestat;
// Retrieve The Player With The Most Rounds Won With Their Rounds
if ($retrievestat == 1)
{
$checkuniquequery = "SELECT COUNT(*) FROM playerstats WHERE roundswon = (SELECT MAX(roundswon) FROM playerstats);"; // Get number of rows that have a roundswon value equal to the max in the table
$stmt = $conn->prepare($checkuniquequery);
echo ($stmt->execute());
if ($stmt->execute() == 1) // If only one row has the max roundswon then get the username + roundswon
{
$mostroundswonquery = "SELECT username, MAX(roundswon) FROM players, playerstats WHERE players.id = playerstats.id";
$stmt = $conn->prepare($mostroundswonquery);
//echo ($stmt->execute());
}
However, when I run this query in phpMyAdmin:
"SELECT COUNT(*) FROM playerstats WHERE roundswon = (SELECT MAX(roundswon) FROM playerstats);"
I get 2 returned as the output.
Any ideas why this is happening and how to fix it?
The execute method on PDO statement ($stmt->execute()) does return either true (if execution was successful) or false if not. It does not return the return value of the SQL statement. On a side node: $stmt->execute() == 1 does behave the same as $stmt->execute() == true !
To get the actual return value you need to fetch the result after execution.
E.g. you can use $stmt->fetch() to get actual result.
Have a look at the documentation to learn more: https://www.php.net/manual/en/class.pdostatement.php

Mysql update query, what if value didn't change? how do I check for that?

When executing UPDATE statement, if value is same as new value than rowCount doesn't change. But for purposes of my application this is also a success. So how do I check for successful update no matter if value changed or not?
$stmt = $conn->prepare('UPDATE users SET name = :name WHERE id = :id');
$result = $stmt->rowCount(); // 1
if ($result == 1) {echo "success!";}
You're not executing the query, merely preparing it. So rowCount() will report an invalid number of rows (the one referring to the last executed query), since no rows were affected yet, and the system doesn't know beforehand how many will be, once you execute the prepared statement with specific param values.
You should check for success upon executing the statement. The execute() method will return true if it succeeds and false otherwise. So if execution success is the only thing you need, then you should do it along the lines of:
$stmt = $conn->prepare('UPDATE users SET name = :name WHERE id = :id');
$result = $stmt->execute($params); // <-- execute first!
if ($result) {echo "success!";}
I agree with Legionar. But instead of count I used to add a column that contains the last update time. So that I can use that to get the entries that got updated after a specific time. In this way I able to reduce the number of entries send to client. The final decision is based on your requirement.
$stmt = $conn->prepare('UPDATE users SET name = :name, updateTime = currentTime WHERE id = :id');
$result = $stmt->rowCount(); // 1
if ($result == 1) {echo "success!";}
I think this cant be done normally, but you can use another column for help.
Add column counter to your users table. And then just increase this value on each update.
$stmt = $conn->prepare('UPDATE users SET name = :name, counter = counter + 1 WHERE id = :id');
$result = $stmt->rowCount(); // 1
if ($result == 1) {echo "success!";}
So now, doesnt matter, if value name will change or not, counter will change each time, so it will return each time 1 if successed.
Or also as Damodaran answered, instead of counter you can use current datetime when doing update.

How to effectively replace (mysql_result(mysql_query()) in PDO?

As my process is almost complete for rewriting web with PDO instead of mysql_* commands I am now testing my changed functions. And It seems that my changed function for mysql_result(mysql_query() always returns true, why is that? Lets see original and changed code:
if (mysql_result(mysql_query("SELECT COUNT(*) FROM account WHERE id='".$_SESSION["user_id"]."' AND online=1"), 0)>0)
{
return true;
}
else
return false;
And changed code here:
$stmt = $db_login->prepare("SELECT COUNT(*) FROM account WHERE id=:id AND online=1");
$stmt->bindValue(':id', $_SESSION["user_id"], PDO::PARAM_INT);
$stmt->execute();
$results_login = $stmt->fetch(PDO::FETCH_ASSOC);
$rows = count($results_login);
if ($rows > 0)
{
return true;
}
else
return false;
So what is wrong with is why it always returns true even when column has online=0? Thank you
$stmt->fetch fetches one row from the result set. What you get out of that is an array containing all the selected columns, looking something like this:
array(
'COUNT(*)' => 42
)
A count() on that array will always result in 1.
You need to check the contents of the fetched row:
if ($result_login['COUNT(*)'] > 0)
It's best to alias this column to a nicer name:
SELECT COUNT(*) AS `count` ...
Then:
if ($result_login['count'] > 0)

What happens when running this code?

I'm running this piece of code:
$sql = "SELECT IF(TIMEDIFF(NOW(),last_update) > '02:00:00',1,0) AS morethan FROM products LIMIT 1";
if($stmt = $this->connect->prepare($sql)) {
$stmt->execute();
$stmt->bind_result($result);
$stmt->fetch();
$stmt->close();
} else {
return false;
}
return $result;
I get 0, that means that the difference I'm checking for it wasn't found ?
Mysql IF works like this:
IF(condition, true, false)
That you revceive 0 in the result "morethan " it means that
TIMEDIFF(NOW(),last_update) > '02:00:00'
is false, in other words the timediff is smaller than 02:00:00
You can rewrite your query just removing the IF:
SELECT (TIMEDIFF(NOW(),last_update) > '02:00:00') morethan FROM products LIMIT 1
Your query will actually non-deterministically get a row (this means you can't predict which row) from the table products and check if it matches your condition. If it does, the query will return 1, otherwise 0. I think that is not your intention, right?
If you want to check if there is any row that fulfills that condition you can do this:
select 1 existsInTable from products
where TIMEDIFF(NOW(),last_update) > '02:00:00'
limit 1
This will return 1 whenever a match is found and an empty resultset when no match is found. You don't even need to check the values returned as you can just count the numbers of intems returned by the query with mysql_num_rows.

PHP PDO statement returns incorrect row count with SELECT?

Why does this portion of code return true even when it shouldn't be?
$stmt = $dbh->prepare("SELECT COUNT(`user_id`) FROM `users` WHERE `username`= :username LIMIT 1");
$stmt->bindParam(':username', $username);
$stmt->execute();
return ($stmt->rowCount() == 1) ? true : false;
If I enter a username in a field that has already been registered, it returns true which then outputs:
That username has already been taken!
But if I enter a username that hasn't been registered, it still returns true and outputs the line above. I'm unsure why this is and how it can be fixed.
I know that the PHP manual states that rowCount() has some issues with SELECT queries, but I can't find a workaround for this that returns the number of rows affected by a SELECT query.
Because COUNT() will always return 1 row, although its value may be 0.
You can do a SELECT TRUE instead:
SELECT TRUE FROM `users` WHERE `username`= :username LIMIT 1
Or you can check if the value is greater than 0:
return ($stmt->fetchColumn() > 0);
BTW - the "? true : false" part is redundant; having the boolean condition by itself does just that.
You are checking the number of result rows. As your query returns always exactly one result row, rowCount() returns 1. The one result row will contain the count, e.g. 0 or 1 in with your query.
You need to check that count value in the result-row or change your query to not return any rows in case the user does not exists.
Try simple without binding:
$res = $dbh->query('SELECT COUNT(`user_id`) AS total FROM `users` WHERE `username`= "'.$username.'" ')->fetch();
return ($res['total'] == 1) ? true : false;

Categories