I have 3 queries named $stmt9, $stmt10 and $stmt11. I need to run the query in order, e.g. run 9, then 10, and finally 11. If there is something wrong, I want to rollback the queries that have been done, e.g. if the problem is on 10, it should rollback 9, or if on 11, then should roll back 10 and 9.
I have the following code, but when something is wrong, sometimes it still runs $stmt9 only, or $stmt9 and $stmt10 but not $stmt11.
How to fix it?
This is the update action:
$this->conn->beginTransaction();
$stmt9 = $this->conn->prepare("UPDATE tableONE SET condition= :condition WHERE `tb1_id`= :id LIMIT 1");
condition
$id = Check_Get_Param($_GET['id']);
$stmt9->bindParam(':condition' , $this->condition);
$stmt9->bindParam(':id' , $id, PDO::PARAM_INT);
$stmt9->execute();
$stmt10 = $this->conn->prepare("UPDATE tableTOW SET disterbute = :dis WHERE tb2_id = :tbl2id LIMIT 1");
$stmt10->bindParam(":counting", $this->counting, PDO::PARAM_INT);
$stmt10->bindParam(":tbl2id ", $this->tbl2id , PDO::PARAM_INT);
$stmt10->execute();
$stmt11 = $this->conn->prepare("DELETE FROM tableTHREE WHERE tb3_id = :id limit 1");
$stmt11->bindParam(":id",$id, PDO::PARAM_INT);
$stmt11->execute();
if($stmt9 && $stmt10 && $stmt11){
$this->conn->commit(); //This will save my changes
header('location:../success.php');
exit;
} else {
$this->conn->rollBack(); //This will undo your changes
echo '<meta http-equiv="refresh" content="0">'. $message;
}
}
}
What you are looking for is called a transaction.
I checked and it is implemented in pdo.
Example taken from the documentation:
<?php
/* Begin a transaction, turning off autocommit */
$dbh->beginTransaction();
/* Change the database schema and data */
$sth = $dbh->exec("DROP TABLE fruit");
$sth = $dbh->exec("UPDATE dessert
SET name = 'hamburger'");
/* Recognize mistake and roll back changes */
$dbh->rollBack();
/* Database connection is now back in autocommit mode */
?>
http://php.net/manual/en/pdo.begintransaction.php
Related
I'm sorry if this has been asked before or if I'm not able to explain in a great way. I've spent hours trying to wrap my head around the issue and I just can't seem to fix this issue. The code is working fine locally, but when I upload it to my server there seems to be some sort of issue with how the server handles/checks differences in time between server and client. Not sure exactly how or what to think. I'm also aware that I'm inserting data into pdo statements incorrectly, I don't care about that at the moment. I will tidy all this up at a later point.
The part of the application that I'm experiencing issues with is when it checks an active shipment (it's a sort of game). I want to compare the timestamp from the database with the current time to see if the time has passed. In the case that the arrival time is past, then I want to set the status of the shipment to 'delivered' as well as add the data to another table called 'storage'.
function check_active_shipment(){
$pdo = pdo();
$username = $_SESSION['username'];
$statement = $pdo->prepare("SELECT * FROM shipments WHERE username LIKE '$username' AND status LIKE 'active' LIMIT 1");
$statement->execute();
$rows = $statement->fetch();
$id = $rows['id'];
if($rows['type'] == "purchase"){
if(time() >= strtotime($rows['arrival'])){
$statement = $pdo->prepare("UPDATE shipments SET status='delivered' WHERE id LIKE '$id'");
$statement->execute();
$statement = $pdo->prepare("INSERT INTO storage (username, crate_type_id, quantity) VALUES (?, ?, ?)");
$statement->bindParam(1, $username);
$statement->bindParam(2, $rows['crate_type_id']);
$statement->bindParam(3, $rows['quantity']);
$statement->execute();
//header("location:index.php");
}
}
else if($rows['type'] == "sale"){
if(time() >= strtotime($rows['arrival'])){
$statement = $pdo->prepare("UPDATE shipments SET status='delivered' WHERE id LIKE ?");
$statement->bindParam(1, $id);
$statement->execute();
$statement = $pdo->prepare("SELECT cash FROM users WHERE username LIKE ?");
$statement->bindParam(1, $username);
$statement->execute();
$user = $statement->fetch();
$cash = $user['cash'] + $rows['value'];
$statement = $pdo->prepare("UPDATE users SET cash=?");
$statement->bindParam(1, $cash);
$statement->execute();
//header("location:index.php");
}
}
}
Let me know if there is any information I'm missing to share.
Would getting the time from the server, rather than using the time() function solve you problem.
Either do a separate query
SELECT NOW()
or add it to your existing query
SELECT *, NOW() as curtime FROM shipments WHERE .....
Have you tried using the DateTime Class? Perhaps it behaves much like you had expected... Here's a snippet on how to use it in your case:
<?php
// ...SOME CODE...
if($rows['type'] == "purchase"){
// TRY USING DateTime CLASS
$arrival = new DateTime($rows['arrival']);
$arrivalTS = $arrival->getTimestamp();
if(time() >= $arrivalTS){
// REST OF THE CODE...
}
}else if($rows['type'] == "sale") {
// TRY USING DateTime CLASS AGAIN
$arrival = new DateTime($rows['arrival']);
$arrivalTS = $arrival->getTimestamp();
if (time() >= $arrivalTS) {
// REST OF THE CODE...
}
}
I am getting annoyed trying to figure out what I am missing to make this code insert a row. It should insert a record where the author is not the current user and the likehistory is 0. Both conditions return as verified when I echo results. So therefore the if statement code should run. However, even with these conditions met, the code always returns the ELSE clause instead. Is there something I am missing below? I feel like the issue lies in $author != $user_ID even though both variables are correct (and currently would equal 2 != 1).
if($author != $user_ID and $likehistory = 0) {
$likepoint = 1;
$yeslike = "INSERT INTO likes(ID,
SID,
WID,
PID) VALUES(
:ID,
:SID,
:WID,
:PID)";
$stmt9 = $dbh->prepare($yeslike);
$stmt9->bindParam(':ID', $user_ID, PDO::PARAM_INT);
$stmt9->bindParam(':SID', $theSID, PDO::PARAM_INT);
$stmt9->bindParam(':WID', $postid, PDO::PARAM_INT);
$stmt9->bindParam(':PID', $likepoint, PDO::PARAM_INT);
$stmt9->execute();
}
else{
echo 'You have already liked this';
}
How can I allow the user submitting a form, to update his entry on "re-submission"
for example
12345678910 (unique id) , submitted the form with selections,
12345678910 , re-submitted with new selections
what's the function responsible for "automatically" updating such kind of form entries.
I know that I can use a check if the entry exists, but how do I update it if it exists and insert it in a new row if it doesn't ...
function checkstudentid($studentid)
{
$con = connectvar();
mysql_select_db("database1", $con);
$result = mysql_query(
"SELECT * FROM table WHERE studentid='$studentid' LIMIT 1");
if(mysql_fetch_array($result) !== false)
....
// I want to add the entry here since it doesn't exist...with checkboxes
// else , I want to update if it already exists
}
Now I'm also not completely positive if the above code will work...but this is what I have for starters, if there is any other way or if the method I'm using is "wrong" , I would appreciate the heads up...or if what I'm trying to is even possible (the way I'm doing it)...
NOTES
I only have one php file which the form submits to.
I am not using a login/registration system
I do not want to display all the data in a table using HTML, just an
"automatic" update if the studentid already exists in the table
If I were using a deprecated method to interact with a database, I would probably just do this:
<?php
function checkstudentid($studentid) {
$con = connectvar();
mysql_select_db("database1", $con);
$result = mysql_query(
"SELECT * FROM table WHERE studentid='$studentid' LIMIT 1");
$query = '';
if (mysql_num_rows($result) > 0) {
$query = "UPDATE table SET column1='$value_one', column2='$value_two' WHERE studentid='$studentid'";
} else {
$query = "INSERT INTO table VALUES('$new_id', '$value_one', '$value_two')";
}
if (mysql_query($query)) {
return true;
} else {
return false;
}
}
?>
But then again, I would use PDO to interact with the DB.
Here is a simple PDO example (you just have to write the function to return the connection):
<?php
function checkstudentid($studentid) {
$update = false;
$dbh = formPDOConnection();
$query = "SELECT studentid FROM table WHERE studentid=:id";
$stmt = $dbh->prepare($query);
$stmt->bindValue(':id', $studentid, PDO::PARAM_STR);
if ($stmt->execute()) {
if ($stmt->rowCount()) {
$update = true;
}
} else {
return 'failure to execute query';
}
// if we just need to update
if ($update) {
$update = "UPDATE table SET value1=:v1,
value2=:v2 WHERE studentid=:id";
$stmt = $dbh->prepare($update);
$stmt->bindValue(':id', $studentid, PDO::PARAM_STR);
$stmt->bindValue(':v1', $value_one, PDO::PARAM_STR);
$stmt->bindValue(':v2', $value_two, PDO::PARAM_STR);
} else {
$insert = "INSERT INTO table VALUES(:id,:v1,v2)";
$stmt = $dbh->prepare($insert);
$stmt->bindValue(':id', $new_id, PDO::PARAM_STR);
$stmt->bindValue(':v1', $value_one, PDO::PARAM_STR);
$stmt->bindValue(':v2', $value_two, PDO::PARAM_STR);
}
return $stmt->execute();
}
?>
Save yourself a headache and stop using mysql_*
You can use INSERT... ON DUPLICATE KEY UPDATE... on your mysql code instead use the logic in your PHP.
Here's a sample:
INSERT INTO `category` (`id`, `name`) VALUES (12, 'color')
ON DUPLICATE KEY UPDATE `name` = 'color';
Reference: http://dev.mysql.com/doc/refman/5.6/en/insert-on-duplicate.html
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();
}
I have a problem with mysql_affected_rows() function in PHP. I use MySQL update, in phpMyAdmin I can see, that 'confirmed' changes from 0 to 1, but mysql_affected_rows still returns 0! I cannot find a solution. My code is:
$query = "UPDATE visits
SET confirmed = 1
WHERE id = ? AND confirmed = 0 AND expire > now() - INTERVAL 10 MINUTE;";
$stmt = $this->conn->stmt_init();
if($stmt->prepare($query)) {
$stmt->bind_param('i',$id); //$id is a function parameter
$res = $stmt->execute();
$stmt->close();
echo mysql_affected_rows();
}
It seems you're using PDO, not the mysql_* functions.
Therefore, you should uso PDOs rowCount function:
$query = "UPDATE visits
SET confirmed = 1
WHERE id = ? AND confirmed = 0 AND expire > now() - INTERVAL 10 MINUTE;";
$stmt = $this->conn->stmt_init();
if($stmt->prepare($query)) {
$stmt->bind_param('i',$id); //$id is a function parameter
$res = $stmt->execute();
echo $stmt->rowCount();
$stmt->close();
}
Use affected_rows to get the number of affected rows when using an UPDATE statement :
$stmt = $this->conn->stmt_init();
if($stmt->prepare($query)) {
$stmt->bind_param('i',$id); //$id is a function parameter
$res = $stmt->execute();
echo $stmt->affected_rows;
$stmt->close();
}
It also needs to be before the close() statement
Since everyone seems to think you using PDO, whereas it looks more like MySQLi to me, here is the MySQLi way:
$query = "
UPDATE visits
SET confirmed = 1
WHERE id = ?
AND confirmed = 0
AND expire > now() - INTERVAL 10 MINUTE
";
$stmt = $this->conn->stmt_init();
if ($stmt->prepare($query)) {
$stmt->bind_param('i', $id); //$id is a function parameter
$res = $stmt->execute();
echo $stmt->affected_rows; // Here's the good stuff
$stmt->close();
}
Use this http://www.php.net/manual/en/pdostatement.rowcount.php
The PDOStatement::rowCount return the number of rows affected by the query
You need to pass the connection as a parameter to the function.
echo mysql_affected_rows($this->conn);
http://php.net/manual/en/function.mysql-affected-rows.php