I'm trying to make a function work, where I ask for a number of free seats left in a car, and if executed, it subtracts 1 from the result and updates the cell in database.
Sql statements must be correct... am I missing out on anything else?
function seatCalc($id){
$stmt=$this->connection->prepare("SELECT seats_left FROM drive WHERE id=?");
$stmt->bind_param("i", $id);
$stmt->bind_result($seat_count);
$stmt->execute();
return $seat_count;
if($seat_count >= 1){
$seat_count -= 1;
$stmt=$this->connection->prepare("UPDATE drive SET seats_left=? WHERE id=?");
$stmt->bind_param("ii", $seat_count, $id);
$stmt->execute();
}
}
It's a part of my university project and unfortunately, I can't reach my professor at the moment.
Thank you in advance!
Your return statement breaks you out of the function before the if block gets processed.
your condition is incorrect;
you have unreached statements after return;
Here is code:
function seatCalc($id){
$stmt=$this->connection->prepare("SELECT seats_left FROM drive WHERE id=?");
$stmt->bind_param("i", $id);
$stmt->bind_result($seat_count);
$stmt->execute();
if($seat_count > 0){
$stmt=$this->connection->prepare("UPDATE drive SET seats_left=seats_left-1 WHERE id=?");
$stmt->bind_param("i", $id);
$stmt->execute();
}
return $seat_count;
}
Also you can substract one with database..
Oh boy
function seatCalc($id){
$stmt=$this->connection->prepare("SELECT seats_left FROM drive WHERE id=:i");
$stmt->bind_param(":i", $id);
$stmt->execute();
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$seat_count = intval($row['seats_left']);
if($seat_count > 0){
$seat_count -= 1;
$stmt=$this->connection->prepare("UPDATE drive SET seats_left=seats_left-1 WHERE id=:id");
$stmt->bind_param(":id", $id);
$stmt->execute();
}
return $seat_count;
}
Related
I have one simple function for delete account from my database. I have written it like below
public function removeAccount($email) {
$response = array('code' => 0, 'error' => false);
$stmt = $this->conn->prepare("SELECT id FROM user WHERE email = ?");
$stmt->bind_param("s", $email);
$stmt->execute();
$result = $stmt->get_result();
if ($result->num_rows) {
$user = $result->fetch_assoc();
$id = $user['id'];
$stmt->close();
$stmt = $this->conn->prepare("DELETE FROM number_list WHERE user_id = ?");
$stmt->bind_param("i", $id);
$stmt->execute();
$stmt->close();
$stmt = $this->conn->prepare("DELETE FROM number_status WHERE user_id = ?");
$stmt->bind_param("i", $id);
$stmt->execute();
$stmt->close();
$stmt = $this->conn->prepare("INSERT INTO old_user(email,serial,premium) SELECT email, device_id, membership FROM user WHERE id = ?");
$stmt->bind_param("i", $id);
$stmt->execute();
$stmt->close();
$stmt = $this->conn->prepare("DELETE FROM user WHERE id = ?");
$stmt->bind_param("i", $id);
$stmt->execute();
$stmt->close();
if ($stmt->affected_rows) {
$response["code"] = 1;
}
}
return $response;
}
Its giving me warning in below line
if ($stmt->affected_rows) {
I have searched way for solve it but does not getting idea whats wrong and what can fix it. Please check and let me know if someone can have idea about it. Thanks a lot.
$stmt = $this->conn->prepare("DELETE FROM user WHERE id = ?");
$stmt->bind_param("i", $id);
$stmt->execute();
if($stmt->affected_rows > 0) { $response["code"] = 1; }
$stmt->close();
In this case, we checked to see if any rows got updated. For reference, here's the usage for mysqli::$affected_rows return values.
-1 - query returned an error; redundant if there is already error handling for execute()
0 - no records updated on UPDATE, no rows matched the WHERE clause or no query has been executed
Greater than 0 - returns number of rows affected; comparable to mysqli_result::$num_rows for SELECT
You're trying to get the number of affected rows from a closed statement.
Instead of
$stmt->execute();
$stmt->close();
if ($stmt->affected_rows) {
$response["code"] = 1;
}
Use
$stmt->execute();
$num_affected_rows = $stmt->affected_rows;
$stmt->close();
if ($num_affected_rows) {
$response["code"] = 1;
}
There are many reasons for this error, but the one I had today was one I have not found documented anywhere.
I had two (2) copies of same virtual machine running and they were both competing in some way that I do not understand well enough to explain, but going into VirtualBox and shutting one of them off solved the problem.
I know this an obscure scenario, but if anyone else runs across the same I hope my answer stops them from wasting time on it like I did.
I made a shop for my site, and got it working but realized it was lacking the ability to properly buy an item. to put it into perspective, you don't walk into a store, grab an item, buy it, grab it again, buy it, grab it again, etc. to get as many as you want. you grab them all at once. my site is lacking such feature. So, I have attempted to change the code that takes the stock, and so far am not succeeding.
I've tried the following:
function takestock($id, $count) {
global $mysqli,$db_table_prefix;
$stmt = $mysqli->prepare("UPDATE ".$db_table_prefix."shop
SET stock = stock - ?
WHERE
id = ?");
$stmt->bind_param("ii", $id, $count);
$result = $stmt->execute();
$stmt->close();
return $result;}
and
function takestock($id, $count) {
global $mysqli,$db_table_prefix;
$stmt = $mysqli->prepare("UPDATE ".$db_table_prefix."shop
SET stock = stock - $count
WHERE
id = ?");
$stmt->bind_param("ii", $id, $count);
$result = $stmt->execute();
$stmt->close();
return $result;}
and
function takestock($id, $count) {
global $mysqli,$db_table_prefix;
$stmt = $mysqli->prepare("UPDATE ".$db_table_prefix."shop
SET stock = stock - ".$count."
WHERE
id = ?");
$stmt->bind_param("ii", $id, $count);
$result = $stmt->execute();
$stmt->close();
return $result;}
but I cant seem to take the count away from the stock!
The order that you bind parameters should correspond to the order you want to use them in your SQL statement. Here, the item count should come first and the id second. I.e., replace the following line:
$stmt->bind_param("ii", $id, $count);
With:
$stmt->bind_param("ii", $count, $id);
I'm currently going thorough a site and replacing all the functions which used to return mysql_fectch_array() results, which are put into while loops elsewhere. I'm trying to make them return the same data in the same format but by using mysqli prepared statements output. I have been successful with the code below in producing the same formatted output for single row results.
public function get_email_settings(){
$stmt = $this->cn->stmt_init();
$stmt->prepare("SELECT * FROM email_setting WHERE user_id = ? LIMIT 1");
$stmt->bind_param("i", $this->user);
$stmt->execute();
$stmt->bind_result(
$row['email_id'],
$row['user_id'],
$row['news'],
$row['new_message'],
$row['new_friend'],
$row['rule_assent'],
$row['agreement_ready'],
$row['agreement_all_assent'],
$row['time_cap'],
$row['donations']
);
$stmt->store_result();
$stmt->fetch();
$stmt->close();
return $row;
}
But how can I get this code to work when it returns more than one row? I want it to be produce the same result as if I had written:
return mysql_fetch_array($result);
Is it possible?
Consider the following adjustment, passing query results into an associative array:
public function get_email_settings(){
$stmt = $this->cn->stmt_init();
$stmt->prepare("SELECT email_id, user_id, news, new_message,
new_friend, rule_assent, agreement_ready,
agreement_all_assent, time_cap, donations
FROM email_setting
WHERE user_id = ? ");
$stmt->bind_param("i", $this->user);
$stmt->execute();
// CREATE RETURN ARRAY
$row = [];
// OBTAIN QUERY RESULTS
$result = $stmt->get_result();
// ITERATE THROUGH RESULT ROWS INTO RETURN ARRAY
while ($data = $stmt->fetch_assoc()) {
$row[] = $data;
}
$stmt->close();
return $row;
}
You will notice I explicitly select the query's fields to avoid an indeterminate loop through query results.
Ok I have managed to get it to work without using get_result()
This is how I did it with alot of help from Parfait and Example of how to use bind_result vs get_result
function saved_rules($user){
$stmt = $this->cn->stmt_init();
$stmt->prepare("SELECT R.rule_id, R.rule_title
FROM Savedrules S
LEFT JOIN Rule R
ON S.saved_rule_id = R.rule_id
WHERE S.saved_user_id = ?");
$stmt->bind_param("i", $user);
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($id, $rule_title);
while ($stmt->fetch()) {
$result[] = Array("rule_id"=>$id,"rule_title"=>$rule_title);
}
$stmt->free_result();
$stmt->close();
return $result;
}
Its not exactly the same output as using a mysql_fetch_array() so where it is used I have to change the loop to:
foreach($saved_rules AS $row){}
from
while ($row = mysql_fetch_array($saved_rules){}
I'm hitting my head to a wall... This is a fraction of my code:
$stmt = $db->prepare("SELECT vote,id FROM votes WHERE post_id = ? AND user_id = ? ");
$stmt->bind_param('ii', $post_id, $user_id);
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($result, $vote_id);
$stmt->fetch();
$num_rows = $stmt->num_rows;
$stmt->close();
if ($num_rows>=1)
{
if ($result!==$vote)
{
$stmt = $db->prepare("UPDATE votes SET vote = ? WHERE id=?");
$stmt->bind_param('ii', $vote, $vote_id);
$stmt->execute();
$stmt->close();
}
else if ($result==$vote)
{
$stmt = $db->prepare("UPDATE votes SET vote = 0 WHERE id=?");
$stmt->bind_param('i', $vote_id);
$stmt->execute();
$stmt->close();
}
}
No errors are shown, the script works just fine until it reaches ELSE IF part. It doesn't update although $vote value is the same as in a database.
!== is a strict comparison operator, and this statement is saying that $result must not be identical (in type as well as value) to $vote. You don't need to be that specific for this.
if ($result!==$vote)
What you should be doing is this:
if ($result != $vote) // only one equal sign, not two
{
...
} else { // they are equal implicitly, no need to redefine the ==
...
}
I should have made such that it is +1 up database instance every time you write a status on its away
problem: right now when writing +1 then the whole time 1
solved: this is how I want when I have 1 point in advance so it must just above the old numbers thus making it for 2 and 3, etc.
if ($stmt = $this->mysqli->prepare('UPDATE bruger SET point=? WHERE id=?')) {
$stmt->bind_param('si', $point, $id);
$point = +1;
$id = $_SESSION["id"];
$stmt->execute();
$stmt->close();
}
You should either do a select query first, then add 1 using PHP and then do an update query, or change the update query so that it automatically adds 1 without using PHP, which is better.
Changing the query would result in the following code:
if ($stmt = $this->mysqli->prepare('UPDATE bruger SET point=point + 1 WHERE id=?')) {
$stmt->bind_param('si', $id);
$id = $_SESSION["id"];
$stmt->execute();
$stmt->close();
}