Does beginTransaction() work with prepare()? - php

I have the following code:
$db->beginTransaction();
$achievement_name = $db->prepare("SELECT `achievement_name` FROM `achievement_names` WHERE `id` = :a_id");
$achievement_name->bindValue(":a_id",$r['achievement_id'],PDO::PARAM_INT);
$achievement_desc = $db->prepare("SELECT `achievement_desc` FROM `achievement_names` WHERE `id` = :a_id");
$achievement_desc->bindValue(":a_id",$r['achievement_id'],PDO::PARAM_INT);
$achievement_image = $db->prepare("SELECT `image` FROM `achievement_names` WHERE `id` = :a_id");
$achievement_image->bindValue(":a_id",$r['achievement_id'],PDO::PARAM_INT);
$db->commit();
Is this possible with PDO? To have the $db->prepare() and bindValue() functions and then committing them? It doesn't seem to be working for me, because they are returning bool(false).

Transaction is using for consistent read or write data. "Preparing" doesn't read or write any data.
So, the answer is: Yes, beginTransaction() work properly with prepare(), but it useless.

Related

update query not working in php and phpmyadmin

i'm trying to create a multiple photo uploading script in php. All seems to be working fine except the update query. tried updating it manually in phpmyadmin and the problem of not updating persists don't know what to do can any experts help me solve this problem.
here is the update query:
try {
$sql1="update photos
set
filename='{$db_file_name}',
upload_date=now() where user='{$_SESSION['id']}' ";
$st1=$conn->prepare($sql1);
$st1->execute();
}
catch (Exception $exc) {
echo $exc->getMessage();
}
First of all, I would verify again whether all the variables you are using are correct (photos, filename, etc.). i.e. compare them letter by letter with your table. If that looks alright, a little more information wouldn't be bad. Are you getting any errors? If so, what are they saying? What else have you tried so far?
Moreover, I would suggest making your code a little easier to read like so:
/* create a prepared statement */
if ($st1 = $conn->prepare("UPDATE `photos` SET `filename` = ?, `upload_date` = ? WHERE `user` = ?")) {
/* bind parameters (ssi = string, string, integer)*/
$st1->bind_param("ssi", $db_file_name, now(), $_SESSION['id']);
/* execute query */
$st1->execute();
/* close statement */
$st1->close();
}
user is a keyword, better use backticks around it. See: https://dev.mysql.com/doc/refman/8.0/en/keywords.html
try {
$sql = "UPDATE `photos`
SET `filename` = :filename,
`upload_date` = NOW()
WHERE `user` = :sess_id";
$stmt = $conn->prepare($sql);
$stmt->bindValue(":sess_id", $_SESSION['id']);
$stmt->bindValue(":filename", $db_file_name);
$stmt->execute();
} catch (....) {
....
}
Perhaps better still, don't use keywords as column names, try userId.

Query works in MySQL but I get 'Query was empty' in PHP

The code below is part of a simple password manager. I get an error saying the Query is empty yet the query works just fine in MySQL. (The 1 and the test value were originally variables I just changed them to values as part of my troubleshooting). I am also aware that the column names user and password may be problematic, but I added ` around them. What else could be wrong with that code?
$change_pass_query = "UPDATE `user` SET `password` = PASSWORD('test') WHERE id = 1";
$change_pass_result = mysql_query($change_pass_query) or die('Error. Change Password Query failed: '. mysql_error());
Try formatting your SQL like this:
UPDATE `user` SET `password` = 'test' WHERE `id` = 1
http://php.net/manual/en/function.mysql-query.php
Notice the warning at the top of that page. Nobody uses mysql_query or any plain mysql functions. Research mysqli/mysqli_query, and PDO.
Here's how you could do this with PDO:
$pdo = new PDO("mysql:host=localhost;dbname=mydb","username","password");
$stmt = $pdo->prepare("UPDATE `user` SET `password` = PASSWORD(:password) WHERE id = :id");
$result = $stmt->execute(array(':password' => "test",':id' => 1));
if (!$result) die('Error. Change Password Query failed: '. mysql_error());
Here's some documentation on PDO: http://php.net/manual/en/book.pdo.php
I ended up renaming all tables and fields so that I didn't use any reserved words, as I thought that the issue might be that. The problem still happened. I then copied my code to a different PHP box, et voila, the code works just fine. I'll have to put it down to an issue with the PHP version/installation on the older box and move on. There is nothing wrong with the code.

PDOStatement's bindValue only working with value of "0"

I'm trying to get data from a MySQL database using PDO. For example, I would run blixUserGetInfo("2767207") if the user's id was 2767207.
But, whenever I run it with a User ID other than 0, blixUserGetInfo("0"), null is returned, and no errors are thrown, even though the supplied ID does exist in the database.
function blixUserGetInfo($userid){
$connection = //database connection
// replacing this with
// "SELECT * FROM `users` WHERE `id` = $userid"
// works for some reason
$statement = "SELECT * FROM `users` WHERE `id` = ?";
$prepared = $connection->prepare($statement);
$prepared->bindValue(1, $userid); //returns TRUE
$prepared->execute(); //also returns TRUE
$code = $prepared->errorCode(); //returns '00000' (no error)
return $prepared->fetch(); //returns null
}
But, If I change $statement from
"SELECT * FROM `users` WHERE `id` = ?"
to
"SELECT * FROM `users` WHERE `id` = $userid"
and remove the bindValue statement, it works as expected.
I've also tried changing the bindValue statement to bindValue(1, $userid, PDO::PARAM_INT), but still have no luck. Both of the times the statement returns true.
Why doesn't the first example work like it should? Is it a bug, am I doing something wrong, or is it expected behavior?
I really dislike this bindValue and bindParam complexity unless it's absolutely necessary. You can simplify your code using parameters for execute
$statement = "SELECT * FROM `users` WHERE `id` = ?";
$prepared = $connection->prepare($statement);
$prepared->execute(array($userid));
While i know this does not answer why bindValue is not working, it takes away having to worry about pass by reference and pass by value stuff which could be a factor in this question.
If this execute does not return an error and your table does have data for that condition than its almost surely going to return it.
Although i didn't confirm it but your act of setting the connection to null before you fetch might be the actual reason you fail to see any data. Why would you set the connection to NULL and try to fetch afterwards ?
I suggest you just not use the bindValue() function anymore.
The bindParam() function works better in this case. Use the value placeholder instead of ?'s (:[placeholder name])
$statement = "SELECT * FROM `users` WHERE `id` = :id";
$prepared = $connection->prepare($statement);
$prepared -> bindParam(":id", $value)
$prepared -> execute();

MySQLi prepared statement silently failing second execution

I am attempting to make a simple system where, once you view forum thread it updates an existing array entry with the current UNIX time in the DB table that holds the user's account information. The column is set to accept MEDIUMTEXT and is set as NOT NULL.
However, while the first prepared statement works as intended and I receive the correct value, and the json_table is correctly re-encoded, the second query does not update the column data. No errors (no matter what error level I set mysqli to). Neither of the parameters I am binding are NULL and are correct.
I am stumped as to why this is happening. MySQLi magic that I haven't learned? Restrictions somewhere?
$DB = GetDatabaseConnection();
$Statement = $DB->prepare("SELECT `forum_newpost_icondata` FROM `user_accounts` WHERE `id` = ?");
print(mysqli_error($DB));
$Statement->bind_param("i", $UserLoggedIn['id']);
$Statement->bind_result($JSONTable);
$Statement->execute();
$PostData = json_decode($JSONTable);
$PostData[$ThreadID] = time();
$PostData = (string)json_encode($PostData);
$Statement->free_result();
$Statement->close();
$Reinsertion = $DB->prepare("UPDATE `user_accounts` SET `forum_newpost_icondata` = ? WHERE `id` = ?");
print(mysqli_error($DB));
$Reinsertion->bind_param("si", $PostData, $UserLoggedIn['id']);
$Reinsertion->execute();
print(mysqli_error($DB)); // Checking after execute is still blank
$DB->close();

PDO prepared statements : How to execute, check affected rows, then fetch a field

I'm very new to PDO - only being told to head in that direction this morning. So, hear me out. I'm trying to rewrite my login verification function from a standard mysql_query() to a PDO prepared statement, but I'm encountering some issues.
The function loginCheck() passes the supplied email and password, then grabs the salt from the matching email, if the number of affected rows of that query was 1, apply the variable $salt to the result of that query.
For the latter portion of the function, I was previously simply using:
// standard mysql query goes here
if (mysql_num_rows($query) == 1) {
$salt = mysql_result($query, 0);
}
Now my entire function looks like:
// new mysql query below
global $dbh;
$stmt = $dbh->prepare("SELECT `salt` FROM `users` WHERE `email`=? LIMIT 1");
$stmt->execute($email);
// not sure what to write here?
but I'm having trouble understanding how to translate the topmost portion of code to something similar in PDO. I'm also probably doing something else wrong here (as always), so point it out to me as well.
I've looked through the PHP manual and I simply cannot understand most of it. Any ideas?
I guess what you're looking for is PDOStatement::rowCount:
$stmt = $dbh->prepare("SELECT `salt` FROM `users` WHERE `email`=? LIMIT 1");
$stmt->execute($email);
if ($stmt->rowCount() == 1) {
$salt = $stmt->fetchColumn(0);
}
I'd rather write this like this though:
$stmt = $dbh->prepare("SELECT `salt` FROM `users` WHERE `email`= :email LIMIT 1");
$stmt->execute(compact('email'));
$user = $stmt->fetch(PDO::FETCH_ASSOC);
if ($user) {
// work with $user['salt']
}
Explicit naming is more robust than depending on column counts.
To understand the manual, you need to understand object oriented notation/concepts. The documentation for the PDO class looks like:
PDO {
...
PDOStatement prepare ( string $statement [, array $driver_options = array() ] )
...
}
This means a PDO object ($dbh in your example), has a method prepare which returns a PDOStatement object. You're using it like this:
$stmt = $dbh->prepare(...);
So $stmt is a PDOStatement object. Knowing this you can look at the documentation for PDOStatement, and see that it has a method int PDOStatement::rowCount ( void ), which you can use.
Here's my favorite PDO tutorial. It answers all your questions:
http://www.phpro.org/tutorials/Introduction-to-PHP-PDO.html

Categories